diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index 3e0776b..1c04fac 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -7,9 +7,6 @@ on: - 'main' tags: - 'v*.*.*' -# release: -# types: -# - published # permissions are needed if pushing to ghcr.io permissions: @@ -49,7 +46,9 @@ jobs: nanoandrew4/ngcplogs # Docker tags based on the following events/attributes tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=tag type=semver,pattern={{raw}} - name: Build all supported architectures run: | - make push PLUGIN_TAG=${{ steps.docker_meta_tag_step.outputs.tags }} \ No newline at end of file + make push PLUGIN_TAG=${{ steps.docker_meta_tag_step.outputs.version }} PLUGIN_NAME=${{ github.repository }} \ No newline at end of file diff --git a/Makefile b/Makefile index 88190bc..562669d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PLUGIN_NAME=nanoandrew4/ngcplogs +PLUGIN_NAME?=nanoandrew4/ngcplogs PLUGIN_TAG?=latest PLUGIN_DIR=./ngcplogs-plugin PLUGIN_SUPPORTED_ARCHS=linux/amd64 linux/arm64 @@ -46,6 +46,7 @@ docker plugin rm -f ${PLUGIN_NAME}:${TAG_ARCH}-${PLUGIN_TAG} || true @echo "### create new plugin ${PLUGIN_NAME}:${TAG_ARCH}-${PLUGIN_TAG} from ${PLUGIN_DIR}-${TAG_ARCH}" docker plugin create ${PLUGIN_NAME}:${TAG_ARCH}-${PLUGIN_TAG} ${PLUGIN_DIR}-${TAG_ARCH} +docker plugin create ghcr.io/${PLUGIN_NAME}:${TAG_ARCH}-${PLUGIN_TAG} ${PLUGIN_DIR}-${TAG_ARCH} endef diff --git a/README.md b/README.md index dfd6466..9515ac8 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ The following [log-opts](https://docs.docker.com/config/containers/logging/confi | extract-json-message | true | Enables unmarshalling JSON messages and sending the jsonPayload as the unmarshalled map. Kind of the whole point of this plugin, but you can disable it so it behaves just like the `gcplogs` plugin if you wish | | local-logging | false | Enables logging to a local file, so logs can be viewed with the `docker logs` command. If false, the command will show no output | | extract-severity | true | Extracts the severity from JSON logs to set them for the log that will be sent to GCP. It will be removed from the jsonPayload section, since it is set at the root level. Currently the supported severity field names to extract are the following: `severity`, `level` | +| extract-msg | true | Extracts the msg field from JSON logs to set the message field GCP expects. It will be removed from the jsonPayload section, since it is set at the root level. Fields named msg are produced for example by the golang log/slog package. | | exclude-timestamp | false | Excludes timestamp fields from the final jsonPayload, since docker sends its own nanosecond precision timestamp for each log. Currently it can remove fields with the following names: `timestamp`, `time`, `ts` | | sleep-interval | 500 | Milliseconds to sleep when there are no logs to send before checking again. The higher the value, the lower the CPU usage will be | | credentials-file | | Absolute path to the GCP credentials JSON file to use when authenticating (only necessary when running the plugin outside of GCP) | @@ -142,4 +143,4 @@ If you want to build the plugin yourself, use the makefile with the following co make all ``` -See the Makefile for other build targets \ No newline at end of file +See the Makefile for other build targets diff --git a/ngcplogger.go b/ngcplogger.go index 15eab8d..bfcb395 100644 --- a/ngcplogger.go +++ b/ngcplogger.go @@ -5,11 +5,12 @@ import ( "encoding/json" "errors" "fmt" - "google.golang.org/api/option" "sync" "sync/atomic" "time" + "google.golang.org/api/option" + "github.com/docker/docker/daemon/logger" "cloud.google.com/go/compute/metadata" @@ -77,6 +78,7 @@ type nGCPLogger struct { extractJsonMessage bool extractSeverity bool excludeTimestamp bool + extractMsg bool } type dockerLogEntry struct { @@ -201,6 +203,7 @@ func New(info logger.Info) (logger.Logger, error) { extractJsonMessage: true, extractSeverity: true, excludeTimestamp: false, + extractMsg: true, } if info.Config[logCmdKey] == "true" { @@ -216,6 +219,9 @@ func New(info logger.Info) (logger.Logger, error) { if info.Config["exclude-timestamp"] == "true" { l.excludeTimestamp = true } + if info.Config["extract-msg"] == "false" { + l.extractMsg = false + } if instanceResource != nil { l.instance = instanceResource @@ -269,6 +275,7 @@ func (l *nGCPLogger) Log(lMsg *logger.Message) error { } else { severity = l.extractSeverityFromPayload(m) l.excludeTimestampFromPayload(m) + l.extractMsgFromPayload(m) m["instance"] = l.instance m["container"] = l.container payload = m @@ -328,6 +335,16 @@ func (l *nGCPLogger) excludeTimestampFromPayload(m map[string]any) { } } +func (l *nGCPLogger) extractMsgFromPayload(m map[string]any) { + + if l.extractMsg { + if msg, exists := m["msg"]; exists { + m["message"] = msg + delete(m, "msg") + } + } +} + func (l *nGCPLogger) Close() error { err := l.logger.Flush() if err != nil {