简介
在上篇中我们实现了查看正在运行中的容器列表,本章节我们来实现 logs 命令,来查看正在运行中的容器的运行日志
源码说明
同时放到了 Gitee 和 Github 上,都可进行获取
本章节对应的版本标签是:5.3,防止后面代码过多,不好查看,可切换到标签版本进行查看
代码实现
实现该功能的主要思路如下:
1 日志的保存:在使用-d 后台运行的时候,我们将文件的输出重定向到文件中,这样就将日志保存到了文件中,提供给后面查看
2 日志的查看:在日志运行过程中,文件已保存到约定的目录,我们只需要读取日志文件内容进行显示即可
运行日志的保存
我们约定将日志文件保存到指定位置
如下,在容器配置中,新增日志文件名称,这样日志文件对应的路径就是:/var/run/mydocker/{容器名}/container.log
 var (  RUNNING             = "running"  STOP                = "stop"  EXIT                = "exited"  DefaultInfoLocation = "/var/run/mydocker/%s/"  ConfigName          = "config.json"  ContainerLogFile    = "container.log")
   复制代码
 
然后将后台运行的容器的输出定向输入到文件中
在启动的时候,将容器名称传递进去,如果没有的话,随机生成(在以前章节中已实现)
 func Run(tty, detach bool, cmdArray []string, config *subsystem.ResourceConfig, volume, containerName string) {  pwd, err := os.Getwd()  if err != nil {    log.Errorf("Run get pwd err: %v", err)    return  }  mntUrl := pwd + "/mnt/"  rootUrl := pwd + "/"  // 传入容器名  parent, writePipe := container.NewParentProcess(tty, containerName, rootUrl, mntUrl, volume)  if err := parent.Start(); err != nil {    log.Error(err)    // 如果fork进程出现异常,但有相关的文件已经进行了挂载,需要进行清理,避免后面运行报错时,需要手工清理    deleteWorkSpace(rootUrl, mntUrl, volume)    return  }  ......}
   复制代码
 
然后在 fork 进程的时候,生成相关的文件,将标准输出重定向到文件中,如下
 func NewParentProcess(tty bool, containerName, rootUrl, mntUrl, volume string) (*exec.Cmd, *os.File) {  ......  if tty {    cmd.Stdin = os.Stdin    cmd.Stdout = os.Stdout    cmd.Stderr = os.Stderr  } else {    // 创建日志保存文件夹    dirUrl := fmt.Sprintf(DefaultInfoLocation, containerName)    if err := os.MkdirAll(dirUrl, 0622); err != nil {      log.Errorf("mkdir dir %s, err: %v", dirUrl, err)      return nil, nil    }
    // 生成日志文件    stdLogFilePath := dirUrl + ContainerLogFile    stdLogFile, err := os.Create(stdLogFilePath)    if err != nil {      log.Errorf("create file %s, err: %v", stdLogFilePath, err)      return nil, nil    }
    // 将输出定向输出到文件    cmd.Stdout = stdLogFile  }  ......}
   复制代码
 
这样,我们就将容器的日志进行了保存
查看容器日志
查看日志就比较简单了,根据容器配置信息,找到日志存放文件,读取进行查看即可
新增 logs 命令:
 func main() {  ......  app.Commands = []cli.Command{    command.InitCommand,    command.RunCommand,    command.CommitCommand,    command.ListCommand,    command.LogCommand,  }  .....}
   复制代码
 
新增 logs 命令解析
 var LogCommand = cli.Command{  Name:  "logs",  Usage: "print logs of a container",  Action: func(context *cli.Context) error {    if len(context.Args()) < 1 {      return fmt.Errorf("Missing container name")    }    containerName := context.Args().Get(0)    return run.LogContainer(containerName)  },}
   复制代码
 
logs 查看的具体实现,读取容器日志文件,进行查看
 func LogContainer(containerName string) error {  dirUrl := fmt.Sprintf(container.DefaultInfoLocation, containerName)  logFilePath := dirUrl + container.ContainerLogFile  file, err := os.Open(logFilePath)  defer file.Close()  if err != nil {    return fmt.Errorf("open file %s, err: %v", logFilePath, err)  }
  content, err := ioutil.ReadAll(file)  if err != nil {    return fmt.Errorf("read file %s, err: %v", logFilePath, err)  }  fmt.Fprint(os.Stdout, string(content))  return nil}
   复制代码
 运行测试
我们运行一个后台的 top 命令容器,然后确认查看相关的信息是否正确:
  root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo   main  ./main run -d -name bird top                                                                                          ✔  ⚡  374  04:58:58{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-04-08T04:59:03+08:00"}{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-04-08T04:59:03+08:00"}{"level":"info","msg":"all command is : top","time":"2022-04-08T04:59:03+08:00"}{"level":"info","msg":"parent process run","time":"2022-04-08T04:59:03+08:00"}
 root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo   main  ./main ps                                                                                                    SIG(127) ↵  ⚡  375  04:59:03ID           NAME        PID         STATUS      COMMAND     CREATED3391689383   bird        28013       running     top         8000-04-04 00:00:00
 root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo   main  tree /var/run/mydocker                                                                                                ✔  ⚡  376  04:59:07/var/run/mydocker└── bird    ├── config.json    └── container.log
1 directory, 2 files
root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo   main  ./main logs bird                                                                                                SIG(127) ↵  ⚡  375  04:59:03Mem: 10193564K used, 22080872K free, 55104K shrd, 106496K buff, 3969012K cachedCPU:  0.0% usr  1.3% sys  0.9% nic 97.5% idle  0.0% io  0.0% irq  0.0% sirqLoad average: 0.19 0.34 0.47 2/1222 6  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
   复制代码
 
评论