go语言读取docker容器的日志

在Go语言中,您可以使用Docker SDK或Docker API来读取Docker容器的日志。

使用Docker SDK

要使用Docker SDK来读取Docker容器的日志,您需要安装Docker SDK并使用其提供的函数进行操作。

安装Docker SDK:

go get -u github.com/docker/docker

获取容器ID

# 短ID
docker ps
CONTAINER ID   IMAGE       COMMAND       CREATED      STATUS         PORTS NAMES
3a09b0e99be9   nginx:latest   "nginx -g 'dae..."  2 hours ago   Up 2 hours   80/tcp   my-nginx

# 长ID
docker inspect <container_name_or_id> --format='{{.Id}}'

# 例如
docker inspect my-nginx --format='{{.Id}}'

获取当前docker的API版本

docker version
Client: Docker Engine - Community
 Version:           20.10.18
 API version:       1.41
 Go version:        go1.18.6
 Git commit:        b40c2f6
 Built:             Thu Sep  8 23:14:08 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.18
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.6
  Git commit:       e42327a
  Built:            Thu Sep  8 23:12:21 2022
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

代码部分

package main

import (
	"context"
	"fmt"
	"io"
	"os"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func readContainerLogs(containerID string) error {
	cli, err := client.NewClientWithOpts(client.WithVersion("1.41")) // 根据您的Docker版本选择合适的API版本
	if err != nil {
		return err
	}

	options := types.ContainerLogsOptions{
		ShowStdout: true,
		ShowStderr: true,
		Follow:     true,
		Tail:       "50", // 获取最后50行日志,根据需求调整
	}

	out, err := cli.ContainerLogs(context.Background(), containerID, options)
	if err != nil {
		return err
	}

	defer out.Close()

	// 从日志流中读取并处理日志行
    // 将日志流转换为扫描器
	scanner := bufio.NewScanner(out)
    //不断读取
	for scanner.Scan() {
		line := scanner.Bytes()

		// 将[]byte切片转换为字符串输出
        // 因为docker前8个字符都是不可见字符,所以需要去掉,从第九个开始读取
		resultString := string(line)[8:]
		fmt.PrintLn(resultString)
	}

	return nil
}

func main() {
	containerID := "3a09b0e99be9" // 将此处替换为要读取日志的容器ID
	err := readContainerLogs(containerID)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

使用Docker API

除了使用Docker SDK之外,您还可以直接使用Docker API来读取Docker容器的日志。

使用Docker API时,您需要向Docker API发送HTTP请求,并从响应中获取日志数据。

先要配置docker支持docker 远程api访问

代码部分

package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func readContainerLogs(containerID string) error {
	url := fmt.Sprintf("http://10.0.0.12:2375/containers/%s/logs?stdout=1&stderr=1", containerID)
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	io.Copy(os.Stdout, resp.Body)
	// logs, err := io.ReadAll(resp.Body)
	// if err != nil {
	// 	return err
	// }

	// // 处理日志数据,例如打印到控制台或保存到文件
	// fmt.Println(string(logs))

	return nil
}

func main() {
	containerID := "3a09b0e99be9" // 将此处替换为要读取日志的容器ID
	err := readContainerLogs(containerID)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
posted @ 2023-07-18 11:14  厚礼蝎  阅读(191)  评论(0编辑  收藏  举报