Golang处理.xlsx文件时程序无日志退出问题

Golang处理.xlsx文件时程序无日志退出问题 我有一个程序,用于打开一个 .xlsx 文件进行解析。 文件看起来像这样 15day_usage_backup/IDT(Boss) New Bill Logic - Cycle 07.01.21-07.15.21.xlsx 我使用了 exc "github.com/360EntSecGroup-Skylar/excelize/v2" 库。

首先,我使用以下代码从 S3 存储桶下载文件:

func (s awss3) GetFile(object string) (string, error) {
	session, err := getSession()
	if err != nil {
		return "", err
	}

	file, err := os.Create(strings.Split(object, "/")[1])
	if err != nil {
		return "", err
	}

	_, err = manager.NewDownloader(session).Download(file, &s3.GetObjectInput{
		Bucket: aws.String(cli.bucket),
		Key:    aws.String(object),
	})
	if err != nil {
		return "", err
	}

	return file.Name(), nil
}

这会下载文件并将其放置在当前工作目录中。

我使用以下代码检查文件的可用性:

	if _, err := os.Stat(f); os.IsNotExist(err) {
		return nil, fmt.Errorf("%s not found: %v", f, err)
	}

我的日志也显示文件存在,并且即将被解析,如下所示: parsing IDT(Boss) New Bill Logic - Cycle 07.01.21-07.15.21.xlsx

我调用:

	file, err := exc.OpenFile(f)
	if err != nil {
		logger.Error(ctx, fmt.Sprintf("error opening %s", f), err)
		return nil, fmt.Errorf("error opening %s: %v", f, err)
	}

这是外部库中的一个函数。

在我的本地机器上的容器中运行时,文件可以被打开,但当我在 ECS 中运行时,任务会退出且没有日志。在我调用外部库的这个函数之后,它没有任何日志就退出了。

我猜想可能是因为文件太大,所以它没有错误就退出了,但检查指标显示它有足够的资源。

Screenshot (3)

我不明白为什么程序在尝试打开这个文件时会退出,并且没有返回日志。 任何想法都会有帮助,谢谢。


更多关于Golang处理.xlsx文件时程序无日志退出问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

更多关于Golang处理.xlsx文件时程序无日志退出问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,问题是资源不足。 在本地使用与ECS相同的资源运行了一个容器 --memory 512m --cpus 0.25

容器被销毁了。

问题可能出现在文件路径或权限上。ECS环境中的工作目录可能与本地不同,导致文件访问失败。以下是排查步骤和示例代码:

  1. 检查文件绝对路径
absPath, err := filepath.Abs(f)
if err != nil {
    logger.Error(ctx, "failed to get absolute path", err)
    return nil, err
}
logger.Info(ctx, fmt.Sprintf("Attempting to open file at: %s", absPath))
  1. 验证文件可读性
file, err := os.Open(f)
if err != nil {
    logger.Error(ctx, fmt.Sprintf("os.Open failed for %s", f), err)
    return nil, err
}
defer file.Close()

// 尝试读取文件头
buf := make([]byte, 8)
_, err = file.Read(buf)
if err != nil {
    logger.Error(ctx, "failed to read file header", err)
    return nil, err
}
  1. 使用完整S3下载路径: 修改GetFile函数,确保返回完整路径:
func (s awss3) GetFile(object string) (string, error) {
    // ... 现有下载代码 ...
    
    // 返回绝对路径
    absPath, err := filepath.Abs(file.Name())
    if err != nil {
        return "", err
    }
    return absPath, nil
}
  1. 检查ECS文件系统权限
// 检查文件权限
info, err := os.Stat(f)
if err != nil {
    logger.Error(ctx, "os.Stat failed", err)
    return nil, err
}
logger.Info(ctx, fmt.Sprintf("File mode: %v", info.Mode()))

// 尝试更改权限
err = os.Chmod(f, 0644)
if err != nil {
    logger.Error(ctx, "chmod failed", err)
}
  1. 添加恢复机制捕获panic
func safeOpenFile(f string) (*exc.File, error) {
    defer func() {
        if r := recover(); r != nil {
            logger.Error(ctx, fmt.Sprintf("Panic recovered: %v", r))
        }
    }()
    
    return exc.OpenFile(f)
}
  1. 验证excelize库版本兼容性
// 在初始化时记录库版本
logger.Info(ctx, fmt.Sprintf("Excelize version: %s", exc.Version))

关键点:ECS环境中容器可能没有写入当前目录的权限,或者工作目录不可预测。建议使用/tmp目录处理临时文件:

func (s awss3) GetFile(object string) (string, error) {
    // 使用系统临时目录
    tmpFile := filepath.Join(os.TempDir(), strings.Split(object, "/")[1])
    file, err := os.Create(tmpFile)
    if err != nil {
        return "", err
    }
    // ... 剩余下载代码 ...
    return tmpFile, nil
}

这些修改应该能帮助定位问题所在。如果问题依旧,检查ECS任务定义中的内存限制是否足够处理该Excel文件。

回到顶部