confgenerator/logging.go (85 lines of code) (raw):

// Copyright 2021 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 confgenerator import ( "context" "fmt" "sort" "strings" "github.com/GoogleCloudPlatform/ops-agent/confgenerator/fluentbit" "github.com/GoogleCloudPlatform/ops-agent/confgenerator/otel" "github.com/GoogleCloudPlatform/ops-agent/internal/platform" ) const InstrumentationSourceLabel = `labels."logging.googleapis.com/instrumentation_source"` const HttpRequestKey = "logging.googleapis.com/httpRequest" func setLogNameProcessor(ctx context.Context, logName string) LoggingProcessorModifyFields { p := platform.FromContext(ctx) hostName := p.Hostname() fields := map[string]*ModifyField{ "logName": { DefaultValue: &logName, }, `labels."compute.googleapis.com/resource_name"`: { DefaultValue: &hostName, }, } r, err := p.GetResource() if err == nil { for k, v := range r.ExtraLogLabels() { v := v fields[fmt.Sprintf("labels.%q", k)] = &ModifyField{ DefaultValue: &v, } } } return LoggingProcessorModifyFields{ Fields: fields, } } // setLogNameComponents generates a series of components that rewrites the tag on log entries tagged `tag` to be `logName`. func setLogNameComponents(ctx context.Context, tag, logName, receiverType string) []fluentbit.Component { p := setLogNameProcessor(ctx, logName) p.Fields[`labels."agent.googleapis.com/log_file_path"`] = &ModifyField{ MoveFrom: `jsonPayload."agent.googleapis.com/log_file_path"`, } // TODO: b/397957994 - Cleanup "receiver_type" logic if no future intended use. // p.Fields[`labels."agent.googleapis.com/receiver_type"`] = &ModifyField{ // StaticValue: &receiverType, // } return p.Components(ctx, tag, "setlogname") } func otelSetLogNameComponents(ctx context.Context, logName string) []otel.Component { // TODO: Prepend `receiver_id.` if it already exists, like the `fluent_forward` receiver? p := setLogNameProcessor(ctx, logName) components, err := p.Processors(ctx) if err != nil { // We're generating a hard-coded config, so this should never fail. panic(err) } return components } // stackdriverOutputComponent generates a component that outputs logs matching the regex `match` using `userAgent`. func stackdriverOutputComponent(ctx context.Context, match, userAgent, storageLimitSize, compress string) fluentbit.Component { config := map[string]string{ // https://docs.fluentbit.io/manual/pipeline/outputs/stackdriver "Name": "stackdriver", "Match_Regex": fmt.Sprintf("^(%s)$", match), "resource": "gce_instance", "stackdriver_agent": userAgent, "http_request_key": HttpRequestKey, // https://docs.fluentbit.io/manual/administration/scheduling-and-retries // After 3 retries, a given chunk will be discarded. So bad entries don't accidentally stay around forever. "Retry_Limit": "3", // https://docs.fluentbit.io/manual/administration/security // Enable TLS support. "tls": "On", // Do not force certificate validation. "tls.verify": "Off", "workers": "8", // Mute these errors until https://github.com/fluent/fluent-bit/issues/4473 is fixed. "net.connect_timeout_log_error": "False", } if r := platform.FromContext(ctx).ResourceOverride; r != nil { mr := r.MonitoredResource() var labels []string for k, v := range mr.Labels { labels = append(labels, fmt.Sprintf("%s=%s", k, v)) } sort.Strings(labels) config["resource"] = mr.Type config["resource_labels"] = strings.Join(labels, ",") } if storageLimitSize != "" { // Limit the maximum number of fluent-bit chunks in the filesystem for the current // output logical destination. config["storage.total_limit_size"] = storageLimitSize } if compress != "" { // Add payload compression config["compress"] = compress } return fluentbit.Component{ Kind: "OUTPUT", Config: config, } }