Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add native cloud logging support #486

Merged
merged 3 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions dataplane/standalone/lucius/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ go_library(
"//dataplane/dplaneopts",
"//dataplane/saiserver",
"//dataplane/saiserver/attrmgr",
"//internal/cloudlog",
"//proto/forwarding",
"@com_github_googlecloudplatform_opentelemetry_operations_go_exporter_trace//:trace",
"@com_github_grpc_ecosystem_go_grpc_middleware_v2//interceptors/logging",
"@io_opentelemetry_go_contrib_detectors_gcp//:gcp",
"@io_opentelemetry_go_contrib_instrumentation_google_golang_org_grpc_otelgrpc//:otelgrpc",
"@io_opentelemetry_go_otel//:otel",
"@io_opentelemetry_go_otel//propagation",
Expand All @@ -31,12 +33,6 @@ go_library(
],
)

go_binary(
name = "lucius",
embed = [":lucius_lib"],
visibility = ["//visibility:public"],
)

pkg_tar(
name = "bin-tar",
srcs = [":lucius"],
Expand Down Expand Up @@ -67,3 +63,9 @@ oci_tarball(
image = ":image",
repo_tags = ["us-west1-docker.pkg.dev/openconfig-lemming/release/lucius:ga"],
)

go_binary(
name = "lucius",
embed = [":lucius_lib"],
visibility = ["//visibility:public"],
)
12 changes: 9 additions & 3 deletions dataplane/standalone/lucius/lucius.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging"
"go.opentelemetry.io/contrib/detectors/gcp"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
Expand All @@ -42,6 +43,7 @@ import (
"github.com/openconfig/lemming/dataplane/dplaneopts"
"github.com/openconfig/lemming/dataplane/saiserver"
"github.com/openconfig/lemming/dataplane/saiserver/attrmgr"
"github.com/openconfig/lemming/internal/cloudlog"

fwdpb "github.com/openconfig/lemming/proto/forwarding"
)
Expand All @@ -53,7 +55,7 @@ var (
_ = flag.String("port_map", "", "Map of modeled port names to Linux interface to as comma seperated list (eg Ethernet8:eth1,Ethernet10,eth2) (deprecated, no-op will be removed in future release)")
_ = flag.Bool("eth_dev_as_lane", true, "If true, when creating ports, use ethX and hardware lane X (deprecated, no-op will always to true in future release)")
_ = flag.Bool("remote_cpu_port", true, "If true, send all packets from/to the CPU port over gRPC (deprecated, no-op will always to true in future release)")
gcpTelemExport = flag.Bool("gcp_telem_export", false, "If true, export OTEL telemetry to GCP")
gcpTelemExport = flag.Bool("gcp_telem_export", false, "If true, export OTEL telemetry and logs to GCP")
gcpProject = flag.String("gcp_project", "", "GCP project to export to, by default it will use project where the GCE instance is running")
hwProfile = flag.String("hw_profile", "", "Path to hardware profile config file.")
)
Expand Down Expand Up @@ -126,10 +128,11 @@ func setupOTelSDK(ctx context.Context) (func(context.Context) error, error) {

var err error
if *gcpTelemExport {
exporter, err = texporter.New(texporter.WithProjectID(*gcpProject))
exporter, err = texporter.New(texporter.WithProjectID(*gcpProject), texporter.WithDestinationProjectQuota())
if err != nil {
return nil, err
}
cloudlog.SetGlobalLogger(ctx, *gcpProject, "lucius")
}

shutdown := func(ctx context.Context) error {
Expand All @@ -141,7 +144,10 @@ func setupOTelSDK(ctx context.Context) (func(context.Context) error, error) {
return err
}

res := resource.Default()
res, err := resource.New(ctx, resource.WithDetectors(gcp.NewDetector()), resource.WithHost(), resource.WithTelemetrySDK())
if err != nil {
return nil, err
}

// Set up propagator.
prop := newPropagator()
Expand Down
17 changes: 10 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ toolchain go1.22.3

require (
cloud.google.com/go/cloudbuild v1.16.3
cloud.google.com/go/logging v1.10.0
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.24.1
github.com/fatih/color v1.15.0
github.com/go-logr/logr v1.4.2
Expand Down Expand Up @@ -38,17 +39,17 @@ require (
github.com/spf13/viper v1.19.0
github.com/stoewer/go-strcase v1.3.0
github.com/vishvananda/netlink v1.2.1-beta.2
go.opentelemetry.io/contrib/detectors/gcp v1.31.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0
go.opentelemetry.io/otel v1.30.0
go.opentelemetry.io/otel v1.31.0
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0
go.opentelemetry.io/otel/log v0.6.0
go.opentelemetry.io/otel/sdk v1.30.0
go.opentelemetry.io/otel/sdk v1.31.0
go.opentelemetry.io/otel/sdk/log v0.6.0
go.opentelemetry.io/otel/sdk/metric v1.27.0
go.opentelemetry.io/otel/trace v1.30.0
go.opentelemetry.io/otel/trace v1.31.0
go.uber.org/mock v0.2.0
golang.org/x/oauth2 v0.21.0
golang.org/x/sys v0.25.0
golang.org/x/sys v0.26.0
google.golang.org/api v0.188.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5
google.golang.org/grpc v1.64.1
Expand All @@ -66,11 +67,12 @@ require (
cloud.google.com/go v0.115.0 // indirect
cloud.google.com/go/auth v0.7.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect
cloud.google.com/go/compute/metadata v0.5.0 // indirect
cloud.google.com/go/compute/metadata v0.5.2 // indirect
cloud.google.com/go/iam v1.1.10 // indirect
cloud.google.com/go/longrunning v0.5.9 // indirect
cloud.google.com/go/pubsub v1.40.0 // indirect
cloud.google.com/go/trace v1.10.10 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/aristanetworks/arista-ceoslab-operator/v2 v2.1.2 // indirect
Expand Down Expand Up @@ -148,12 +150,13 @@ require (
github.com/vishvananda/netns v0.0.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.31.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
Expand Down
28 changes: 16 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,8 @@ cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZ
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo=
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
Expand Down Expand Up @@ -1342,6 +1342,8 @@ gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zum
git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 h1:cZpsGsWTIFKymTA0je7IIvi1O7Es7apb9CF3EQlOcfE=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2/go.mod h1:itPGVDKf9cC/ov4MdvJ2QZ0khw4bfoo9jzwTJlaxy2k=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.24.1 h1:01bHLeqkrxYSkjvyTBEZ8rxBxDhWm1snWGEW73Te4lU=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.24.1/go.mod h1:UFO9jC3njhKdD/ymLnaKi7Or5miVWq06LvRWQNFfnTU=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.48.1 h1:oTX4vsorBZo/Zdum6OKPA4o7544hm6smoRv1QjpTwGo=
Expand Down Expand Up @@ -1953,6 +1955,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/detectors/gcp v1.31.0 h1:G1JQOreVrfhRkner+l4mrGxmfqYCAuy76asTDAo0xsA=
go.opentelemetry.io/contrib/detectors/gcp v1.31.0/go.mod h1:tzQL6E1l+iV44YFTkcAeNQqzXUiekSYP9jjJjXwEd00=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg=
Expand All @@ -1970,8 +1974,8 @@ go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znn
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0 h1:bZHOb8k/CwwSt0DgvgaoOhBXWNdWqFWaIsGTtg1H3KE=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.6.0/go.mod h1:XlV163j81kDdIt5b5BXCjdqVfqJFy/LJrHA697SorvQ=
go.opentelemetry.io/otel/log v0.6.0 h1:nH66tr+dmEgW5y+F9LanGJUBYPrRgP4g2EkmPE3LeK8=
Expand All @@ -1981,13 +1985,13 @@ go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzu
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
go.opentelemetry.io/otel/sdk/log v0.6.0 h1:4J8BwXY4EeDE9Mowg+CyhWVBhTSLXVXodiXxS/+PGqI=
go.opentelemetry.io/otel/sdk/log v0.6.0/go.mod h1:L1DN8RMAduKkrwRAFDEX3E3TLOq46+XMGSbUfHU/+vE=
go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI=
Expand All @@ -1997,8 +2001,8 @@ go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
Expand Down Expand Up @@ -2342,8 +2346,8 @@ golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand Down
13 changes: 13 additions & 0 deletions internal/cloudlog/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "cloudlog",
srcs = ["cloudlog.go"],
importpath = "github.com/openconfig/lemming/internal/cloudlog",
visibility = ["//:__subpackages__"],
deps = [
"@com_google_cloud_go_logging//:logging",
"@com_google_cloud_go_logging//apiv2/loggingpb",
"@io_opentelemetry_go_otel_trace//:trace",
],
)
115 changes: 115 additions & 0 deletions internal/cloudlog/cloudlog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cloudlog

import (
"context"
"fmt"
"log/slog"
"os"
"os/signal"
"runtime"
"syscall"
"time"

"cloud.google.com/go/logging"
"cloud.google.com/go/logging/apiv2/loggingpb"
"go.opentelemetry.io/otel/trace"
)

// SetGlobal sets the global slog to use output a GCP cloud logging and stderr
func SetGlobalLogger(ctx context.Context, project, logName string) error {
cl, err := logging.NewClient(ctx, fmt.Sprintf("projects/%s", project))
if err != nil {
return err
}

h := &cloudLogHandle{
Handler: slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{}),
l: cl.Logger(logName),
project: project,
}

t := time.NewTicker(time.Second)

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

go func() {
for {
select {
case <-sigs:
h.l.Flush()
case <-t.C:
if err := h.l.Flush(); err != nil {
fmt.Fprintf(os.Stderr, "log flush err: %v", err)
}
}
}
}()

slog.SetDefault(slog.New(h))
return nil
}

type cloudLogHandle struct {
slog.Handler
l *logging.Logger
project string
}

func (t *cloudLogHandle) Handle(ctx context.Context, record slog.Record) error {
payload := map[string]string{
"message": record.Message,
}

entry := logging.Entry{
Timestamp: record.Time,
}
switch record.Level {
case slog.LevelError:
entry.Severity = logging.Error
case slog.LevelWarn:
entry.Severity = logging.Warning
case slog.LevelInfo:
entry.Severity = logging.Info
case slog.LevelDebug:
entry.Severity = logging.Debug
}
record.Attrs(func(a slog.Attr) bool {
payload[a.Key] = a.Value.String()
return true
})

entry.Payload = payload

if s := trace.SpanContextFromContext(ctx); s.IsValid() {
entry.Trace = fmt.Sprintf("projects/%s/traces/%s", t.project, s.TraceID().String())
entry.SpanID = s.SpanID().String()
entry.TraceSampled = s.IsSampled()
}

fs := runtime.CallersFrames([]uintptr{record.PC})
f, _ := fs.Next()
entry.SourceLocation = &loggingpb.LogEntrySourceLocation{
File: f.File,
Line: int64(f.Line),
Function: f.Function,
}

t.l.Log(entry)

return t.Handler.Handle(ctx, record)
}
Loading
Loading