Skip to content

Commit

Permalink
Change container log output CRI format
Browse files Browse the repository at this point in the history
  • Loading branch information
nwneisen committed Sep 11, 2023
1 parent 6b452f9 commit 858c294
Show file tree
Hide file tree
Showing 28 changed files with 1,839 additions and 6 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ name: Integration Tests

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]

jobs:
integration:
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:

- name: Set up Go 1.19.10
uses: actions/setup-go@v1
with:
Expand Down Expand Up @@ -70,7 +69,6 @@ jobs:
with:
repository: kubernetes-sigs/cri-tools
path: src/sigs.k8s.io/cri-tools
ref: 5fd98895f3bbf8a3ba2d25e93fa95ba1e2ae0923

- name: Build cri-tools
working-directory: src/sigs.k8s.io/cri-tools
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ release: static-linux deb rpm cross-arm cross-mac cross-win ## build the release
.PHONY: dev
dev: cri-dockerd ## Run cri-docker in a running minikube
./scripts/replace-in-minikube

.PHONY: docs
docs:
hugo server --source docs/

3 changes: 2 additions & 1 deletion core/container_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package core
import (
"context"
"fmt"

v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
)

Expand All @@ -30,7 +31,7 @@ func (ds *dockerService) StartContainer(
err := ds.client.StartContainer(r.ContainerId)

// Create container log symlink for all containers (including failed ones).
if linkError := ds.createContainerLogSymlink(r.ContainerId); linkError != nil {
if linkError := ds.createContainerKubeLogFile(r.ContainerId); linkError != nil {
// Do not stop the container if we failed to create symlink because:
// 1. This is not a critical failure.
// 2. We don't have enough information to properly stop container here.
Expand Down
105 changes: 105 additions & 0 deletions core/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package core

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
Expand All @@ -26,6 +27,7 @@ import (
"time"

"github.com/Mirantis/cri-dockerd/config"
"github.com/nxadm/tail"

"github.com/armon/circbuf"
dockertypes "github.com/docker/docker/api/types"
Expand Down Expand Up @@ -85,6 +87,7 @@ func (ds *dockerService) GetContainerLogs(
stderr = SharedLimitWriter(stderr, &max)
stdout = SharedLimitWriter(stdout, &max)
}

sopts := libdocker.StreamOptions{
OutputStream: stdout,
ErrorStream: stderr,
Expand Down Expand Up @@ -155,6 +158,7 @@ func (ds *dockerService) getContainerLogPath(containerID string) (string, string
if err != nil {
return "", "", fmt.Errorf("failed to inspect container %q: %v", containerID, err)
}

return info.Config.Labels[containerLogPathLabelKey], info.LogPath, nil
}

Expand Down Expand Up @@ -222,3 +226,104 @@ func (ds *dockerService) removeContainerLogSymlink(containerID string) error {
}
return nil
}

// createContainerKubeLogFile creates the kube log file for docker container log.
func (ds *dockerService) createContainerKubeLogFile(containerID string) error {
kubePath, dockerPath, err := ds.getContainerLogPath(containerID)
if err != nil {
return fmt.Errorf("failed to get container %q log path: %v", containerID, err)
}

if kubePath == "" {
logrus.Debugf("Container log path for Container ID %s isn't specified, will not create kubepath", containerID)
return nil
}

if dockerPath != "" {
// Only create the kube log file when container log path is specified and log file exists.
// Delete possibly existing file first
if err = ds.os.Remove(kubePath); err == nil {
logrus.Debugf("Deleted previously existing kube log file: %s", kubePath)
}

_, err = os.Create(kubePath)
if err != nil {
return fmt.Errorf(
"failed to create the kube log file %q to the container log file %q for container %q: %v",
kubePath,
dockerPath,
containerID,
err,
)

}

go func() {
// Open the kube file for output
kubeFile, err := os.OpenFile(kubePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
logrus.Errorf(
"failed to open kube log file %s: %v",
kubePath,
err,
)
panic(err)
}
defer kubeFile.Close()

// Tail the docker file for input
t, err := tail.TailFile(dockerPath, tail.Config{
Follow: true,
ReOpen: true})
if err != nil {
logrus.Errorf(
"failed to tail docker log file %s: %v",
dockerPath,
err,
)
panic(err)
}
// Watch for changes to be copied over
for line := range t.Lines {
logLine := Log{}
json.Unmarshal([]byte(line.Text), &logLine)

_, err := kubeFile.WriteString(logLine.CRIFormat())
if err != nil {
logrus.Errorf(
"failed to write to kube log file %s: %v",
kubePath,
err,
)
return
}
}
}()
} else {
supported, err := ds.IsCRISupportedLogDriver()
if err != nil {
logrus.Errorf("Failed to check supported logging driver for CRI: %v", err)
return nil
}

if supported {
logrus.Info("Cannot create kube log file because container log file doesn't exist!")
} else {
logrus.Debug("Unsupported logging driver by CRI")
}
}

return nil
}

type Log struct {
Log string `json:"log"`
Stream string `json:"stream"`
Flags string `json:"flags"`
Time time.Time `json:"time"`
}

// CRIFormat returns the log in the CRI format
func (l Log) CRIFormat() string {
return fmt.Sprintf("%s %s %s %s", l.Time.Format(time.RFC3339), l.Stream, l.Flags, l.Log)
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/docker/go-connections v0.4.0
github.com/emicklei/go-restful v2.16.0+incompatible
github.com/golang/mock v1.6.0
github.com/nxadm/tail v1.4.8
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc3
github.com/opencontainers/runc v1.1.5
Expand Down Expand Up @@ -124,6 +125,7 @@ require (
google.golang.org/genproto v0.0.0-20230106154932-a12b697841d9 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/cloud-provider v0.22.8 // indirect
Expand Down
3 changes: 3 additions & 0 deletions vendor/github.com/nxadm/tail/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions vendor/github.com/nxadm/tail/CHANGES.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions vendor/github.com/nxadm/tail/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/nxadm/tail/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions vendor/github.com/nxadm/tail/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions vendor/github.com/nxadm/tail/ratelimiter/Licence

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 858c294

Please sign in to comment.