在上篇中我們實現了查看正在運行中的容器列表,本章節我們來實現logs命令,來查看正在運行中的容器的運行日志
同時放到了Gitee和Github上,都可進行獲取
查看docker容器日志?本章節對應的版本標簽是:5.3,防止后面代碼過多,不好查看,可切換到標簽版本進行查看
實現該功能的主要思路如下:
1 日志的保存:在使用-d后臺運行的時候,我們將文件的輸出重定向到文件中,這樣就將日志保存到了文件中,提供給后面查看
linux命令格式?2 日志的查看:在日志運行過程中,文件已保存到約定的目錄,我們只需要讀取日志文件內容進行顯示即可
我們約定將日志文件保存到指定位置
如下,在容器配置中,新增日志文件名稱,這樣日志文件對應的路徑就是:/var/run/mydocker/{容器名}/container.log
var (RUNNING = "running"STOP = "stop"EXIT = "exited"DefaultInfoLocation = "/var/run/mydocker/%s/"ConfigName = "config.json"ContainerLogFile = "container.log"
)
docker查看日志?然后將后臺運行的容器的輸出定向輸入到文件中
在啟動的時候,將容器名稱傳遞進去,如果沒有的話,隨機生成(在以前章節中已實現)
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.Stdincmd.Stdout = os.Stdoutcmd.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 + ContainerLogFilestdLogFile, err := os.Create(stdLogFilePath)if err != nil {log.Errorf("create file %s, err: %v", stdLogFilePath, err)return nil, nil}// 將輸出定向輸出到文件cmd.Stdout = stdLogFile}......
}
linux初學者掌握的命令、這樣,我們就將容器的日志進行了保存
查看日志就比較簡單了,根據容器配置信息,找到日志存放文件,讀取進行查看即可
新增logs命令:
func main() {......app.Commands = []cli.Command{command.InitCommand,command.RunCommand,command.CommitCommand,command.ListCommand,command.LogCommand,}.....
}
docker日志收集方案、新增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.ContainerLogFilefile, 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:03
ID NAME PID STATUS COMMAND CREATED
3391689383 bird 28013 running top 8000-04-04 00:00:00root@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main tree /var/run/mydocker ? ? 376 04:59:07
/var/run/mydocker
└── bird├── config.json└── container.log1 directory, 2 filesroot@lw-Code-01-Series-PF5NU1G ~/code/go/dockerDemo main ./main logs bird SIG(127) ? ? 375 04:59:03
Mem: 10193564K used, 22080872K free, 55104K shrd, 106496K buff, 3969012K cached
CPU: 0.0% usr 1.3% sys 0.9% nic 97.5% idle 0.0% io 0.0% irq 0.0% sirq
Load average: 0.19 0.34 0.47 2/1222 6PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态