Skip to content

Commit 8cce90c

Browse files
committed
Initial commit
1 parent d06ea2e commit 8cce90c

35 files changed

+4290
-1
lines changed

.github/codecov.yml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
coverage:
2+
status:
3+
project:
4+
default:
5+
informational: true
6+
patch:
7+
default:
8+
informational: true
9+
ignore:
10+
# All 'pb.go's.
11+
- "**/*.pb.go"
12+
# Tests and test related files.
13+
- "**/test"
14+
- "**/testdata"
15+
- "**/testutils"
16+
- "benchmark"
17+
- "interop"
18+
# Other submodules.
19+
- "cmd"
20+
- "examples"
21+
- "gcp"
22+
- "security"
23+
- "stats/opencensus"
24+
comment:
25+
layout: "header, diff, files"

.github/dependabot.yml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "github-actions"
9+
directory: "/"
10+
schedule:
11+
interval: "monthly"
12+
groups:
13+
github-actions:
14+
patterns:
15+
- "*"
16+
ignore:
17+
- dependency-name: "*"
18+
update-types: ["version-update:semver-major"]

.github/workflows/ci.yml

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Workflow for CI
2+
on: [ push, pull_request ]
3+
jobs:
4+
run:
5+
runs-on: ubuntu-latest
6+
strategy:
7+
matrix:
8+
go-version: [ '1.21', '1.22' ]
9+
steps:
10+
- name: Checkout
11+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
12+
with:
13+
fetch-depth: 0
14+
15+
- name: Setup Go ${{ matrix.go-version }}
16+
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
17+
with:
18+
go-version: ${{ matrix.go-version }}
19+
20+
- name: Ensure the Go module is nice and tidy
21+
run: |
22+
go mod tidy && git diff --exit-code go.mod go.sum
23+
# We set the shell explicitly, here, and in other golang test actions,
24+
# as by default multi-line shell scripts do not error out on the first
25+
# failed command. Since we want an error reported if any of the lines
26+
# fail, we set the shell explicitly:
27+
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions?ref=cloudtechsimplified.com#exit-codes-and-error-action-preference
28+
shell: bash
29+
30+
- name: Install Tools
31+
run: |
32+
pushd "$(mktemp -d)"
33+
go mod init example.com/m # fake module
34+
go install github.com/onsi/ginkgo/v2/[email protected]
35+
go install honnef.co/go/tools/cmd/[email protected]
36+
popd
37+
shell: bash
38+
39+
- name: Verify Go Modules Setup
40+
run: go mod verify
41+
shell: bash
42+
43+
- name: Build
44+
run: go build -v ./...
45+
shell: bash
46+
47+
- name: Sanity Check (staticcheck)
48+
run: staticcheck ./...
49+
shell: bash
50+
51+
- name: Test
52+
run: ginkgo -v -race -coverprofile=coverage.out -coverpkg=./... ./...
53+
shell: bash
54+
55+
- name: Upload coverage to Codecov
56+
uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0
57+
with:
58+
token: ${{ secrets.CODECOV_TOKEN }}
59+
slug: maguro/gslog
60+
flags: smart-tests
61+
verbose: true
62+

README.md

+80-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,81 @@
11
# gslog
2-
An slog Handler for Google Cloud Logging
2+
3+
![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.21-%23007d9c)
4+
[![Documentation](https://godoc.org/github.com/maguro/gslog?status.svg)](http://godoc.org/github.com/maguro/gslog)
5+
[![Go Report Card](https://goreportcard.com/badge/github.com/maguro/gslog)](https://goreportcard.com/report/github.com/maguro/gslog)
6+
[![codecov](https://codecov.io/gh/maguro/gslog/graph/badge.svg?token=3FAJJ2SIZB)](https://codecov.io/gh/maguro/gslog)
7+
[![License](https://img.shields.io/github/license/maguro/gslog)](./LICENSE)
8+
9+
A Google Cloud Logging [Handler](https://pkg.go.dev/log/slog#Handler) implementation
10+
for [slog](https://go.dev/blog/slog).
11+
12+
---
13+
14+
Critical level log records will be sent synchronously.
15+
16+
## Install
17+
18+
```sh
19+
go get m4o.io/gslog
20+
```
21+
22+
**Compatibility**: go >= 1.21
23+
24+
## Example Usage
25+
26+
First create a [Google Cloud Logging](https://pkg.go.dev/cloud.google.com/go/logging)
27+
`logging.Client` to use throughout your application:
28+
29+
```go
30+
ctx := context.Background()
31+
client, err := logging.NewClient(ctx, "my-project")
32+
if err != nil {
33+
// TODO: Handle error.
34+
}
35+
```
36+
37+
Usually, you'll want to add log entries to a buffer to be periodically flushed
38+
(automatically and asynchronously) to the Cloud Logging service. Use the
39+
logger when creating the new `gslog.GcpHandler` which is passed to `slog.New()`
40+
to obtain a `slog`-based logger.
41+
42+
```go
43+
loggger := client.Logger("my-log")
44+
45+
h := gslog.NewGcpHandler(loggger)
46+
l := slog.New(h)
47+
48+
l.Info("How now brown cow?")
49+
```
50+
51+
Writing critical, or higher, log level entries will be sent synchronously.
52+
53+
```go
54+
l.Log(context.Background(), gslog.LevelCritical, "Danger, Will Robinson!")
55+
```
56+
57+
Close your client before your program exits, to flush any buffered log entries.
58+
59+
```go
60+
err = client.Close()
61+
if err != nil {
62+
// TODO: Handle error.
63+
}
64+
```
65+
66+
## Logger Configuration Options
67+
68+
Creating a Google Cloud Logging [Handler](https://pkg.go.dev/log/slog#Handler) using `gslog.NewGcpHandler(logger, ...options)` accepts the
69+
following options:
70+
71+
| Configuration option | Arguments | Description |
72+
|----------------------------------------|:------------------:|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
73+
| `gslog.WithLogLeveler(leveler)` | `slog.Leveler` | Specifies the `slog.Leveler` for logging. Explicitly setting the log level here takes precedence over the other options. |
74+
| `gslog.WithLogLevelFromEnvVar(envVar)` | `string` | Specifies the log level for logging comes from tne environmental variable specified by the key. |
75+
| `gslog.WithDefaultLogLeveler()` | `slog.Leveler` | Specifies the default `slog.Leveler` for logging. |
76+
| `gslog.WithSourceAdded()` | | Causes the handler to compute the source code position of the log statement and add a `slog.SourceKey` attribute to the output. |
77+
| `gslog.WithLabels()` | | Adds any labels found in the context to the `logging.Entry`'s `Labels` field. |
78+
| `gslog.WithReplaceAttr(mapper)` | `gslog.AttrMapper` | Specifies an attribute mapper used to rewrite each non-group attribute before it is logged. |
79+
| `otel.WithOtelBaggage()` | | Directs that the `slog.Handler` to include [OpenTelemetry baggage](https://opentelemetry.io/docs/concepts/signals/baggage/). The `baggage.Baggage` is obtained from the context, if available, and added as attributes. |
80+
| `otel.WithOtelTracing()` | | Directs that the `slog.Handler` to include [OpenTelemetry tracing](https://opentelemetry.io/docs/concepts/signals/traces/). Tracing information is obtained from the `trace.SpanContext` stored in the context, if provided. |
81+
| `k8s.WithPodinfoLabels(root)` | `string` | Directs that the `slog.Handler` to include labels from the [Kubernetes Downward API](https://kubernetes.io/docs/concepts/workloads/pods/downward-api/) podinfo `labels` file. The labels file is expected to be found in the directory specified by root and MUST be named "labels", per the Kubernetes Downward API for Pods. |

attr.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2024 The original author or authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package gslog
16+
17+
import (
18+
"log/slog"
19+
)
20+
21+
// AttrMapper is called to rewrite each non-group attribute before it is logged.
22+
// The attribute's value has been resolved (see [Value.Resolve]).
23+
// If replaceAttr returns a zero Attr, the attribute is discarded.
24+
//
25+
// The built-in attribute with key "message" is passed to this function.
26+
//
27+
// The first argument is a list of currently open groups that contain the
28+
// Attr. It must not be retained or modified. replaceAttr is never called
29+
// for Group attributes, only their contents. For example, the attribute
30+
// list
31+
//
32+
// Int("a", 1), Group("g", Int("b", 2)), Int("c", 3)
33+
//
34+
// results in consecutive calls to replaceAttr with the following arguments:
35+
//
36+
// nil, Int("a", 1)
37+
// []string{"g"}, Int("b", 2)
38+
// nil, Int("c", 3)
39+
//
40+
// AttrMapper can be used to change the default keys of the built-in
41+
// attributes, convert types (for example, to replace a `time.Time` with the
42+
// integer seconds since the Unix epoch), sanitize personal information, or
43+
// remove attributes from the output.
44+
type AttrMapper func(groups []string, a slog.Attr) slog.Attr

doc.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2024 The original author or authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package gslog contains a GCP logging implementation of slog.Handler.
16+
package gslog

0 commit comments

Comments
 (0)