Skip to content

Commit

Permalink
Write enabled_receivers and feature_tracking metrics to OTLP json.
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscovalentecastro committed Mar 11, 2025
1 parent 035a837 commit 63ebf59
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 8 deletions.
6 changes: 6 additions & 0 deletions cmd/google_cloud_ops_agent_engine/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/ops-agent/confgenerator"
"github.com/GoogleCloudPlatform/ops-agent/internal/healthchecks"
"github.com/GoogleCloudPlatform/ops-agent/internal/logs"
"github.com/GoogleCloudPlatform/ops-agent/internal/self_metrics"
)

var (
Expand Down Expand Up @@ -59,6 +60,11 @@ func run() error {
return err
}

err = self_metrics.CollectOpsAgentSelfMetricsToOTLPJSON(ctx, uc, uc)
if err != nil {
return err
}

// Log the built-in and merged config files to STDOUT. These are then written
// by journald to var/log/syslog and so to Cloud Logging once the ops-agent is
// running.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ require (
)

require (
go.opentelemetry.io/collector/pdata v1.4.0
golang.org/x/sync v0.10.0
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed
gopkg.in/yaml.v3 v3.0.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/collector/pdata v1.4.0 h1:cA6Pr7Z2V7mE+i7FmYpavX7nefzd6H4CICgW0T9aJX0=
go.opentelemetry.io/collector/pdata v1.4.0/go.mod h1:0Ttp4wQinhV5oJTd9MjyvUegmZBO9O0nrlh/+EDLw+Q=
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.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
Expand Down
119 changes: 111 additions & 8 deletions internal/self_metrics/self_metrics.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Google LLC
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -18,11 +18,13 @@ import (
"context"
"fmt"
"log"
"os"
"strings"
"time"

mexporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric"
"github.com/GoogleCloudPlatform/ops-agent/confgenerator"
"go.opentelemetry.io/collector/pdata/pmetric"
"go.opentelemetry.io/contrib/detectors/gcp"
"go.opentelemetry.io/otel/attribute"
metricapi "go.opentelemetry.io/otel/metric"
Expand All @@ -33,8 +35,20 @@ import (
"google.golang.org/grpc/status"
)

const (
agentMetricNamespace string = "agent.googleapis.com"
enabledReceiversMetricName string = "agent/ops_agent/enabled_receivers"
featureTrackingMetricName string = "agent/internal/ops/feature_tracking"
enabledReceiversOTLPJSONFilePath string = "/var/run/google-cloud-ops-agent-opentelemetry-collector/enabledReceiversOTLP.json"
featureTrackingOTLPJSONFilePath string = "/var/run/google-cloud-ops-agent-opentelemetry-collector/featureTrackingOTLP.json"
)

func getFullAgentMetricName(metricName string) string {
return fmt.Sprintf("%s/%s", agentMetricNamespace, metricName)
}

func agentMetricsPrefixFormatter(d metricdata.Metrics) string {
return fmt.Sprintf("agent.googleapis.com/%s", d.Name)
return getFullAgentMetricName(d.Name)
}

type EnabledReceivers struct {
Expand Down Expand Up @@ -70,7 +84,7 @@ func InstrumentEnabledReceiversMetric(ctx context.Context, uc *confgenerator.Uni
}

_, err = meter.Int64ObservableGauge(
"agent/ops_agent/enabled_receivers",
enabledReceiversMetricName,
metricapi.WithInt64Callback(
func(ctx context.Context, observer metricapi.Int64Observer) error {
for rType, count := range eR.MetricsReceiverCountsByType {
Expand Down Expand Up @@ -104,7 +118,7 @@ func InstrumentFeatureTrackingMetric(ctx context.Context, userUc, mergedUc *conf
return err
}
_, err = meter.Int64ObservableGauge(
"agent/internal/ops/feature_tracking",
featureTrackingMetricName,
metricapi.WithInt64Callback(
func(ctx context.Context, observer metricapi.Int64Observer) error {
for _, f := range features {
Expand Down Expand Up @@ -137,11 +151,11 @@ func CreateFeatureTrackingMeterProvider(exporter metricsdk.Exporter, res *resour
metricsdk.WithView(
metricsdk.NewView(
metricsdk.Instrument{
Name: "agent/internal/ops/feature_tracking",
Name: featureTrackingMetricName,
Kind: metricsdk.InstrumentKindObservableGauge,
},
metricsdk.Stream{
Name: "agent/internal/ops/feature_tracking",
Name: featureTrackingMetricName,
Aggregation: metricsdk.AggregationDefault{},
},
)),
Expand All @@ -160,11 +174,11 @@ func CreateEnabledReceiversMeterProvider(exporter metricsdk.Exporter, res *resou
metricsdk.WithView(
metricsdk.NewView(
metricsdk.Instrument{
Name: "agent/ops_agent/enabled_receivers",
Name: enabledReceiversMetricName,
Kind: metricsdk.InstrumentKindObservableGauge,
},
metricsdk.Stream{
Name: "agent/ops_agent/enabled_receivers",
Name: enabledReceiversMetricName,
Aggregation: metricsdk.AggregationDefault{},
},
)),
Expand Down Expand Up @@ -242,3 +256,92 @@ func CollectOpsAgentSelfMetrics(ctx context.Context, userUc, mergedUc *confgener
}
}
}

func CollectEnabledReceiversMetricToOLTPJSON(ctx context.Context, uc *confgenerator.UnifiedConfig) error {
eR, err := CountEnabledReceivers(ctx, uc)
if err != nil {
return err
}

metrics := pmetric.NewMetrics()
gaugeMetric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
gaugeMetric.SetName(getFullAgentMetricName(enabledReceiversMetricName))
dataPoints := gaugeMetric.SetEmptyGauge().DataPoints()

for rType, count := range eR.MetricsReceiverCountsByType {
point := dataPoints.AppendEmpty()
point.SetIntValue(int64(count))
attributes := point.Attributes()
attributes.PutStr("telemetry_type", "metrics")
attributes.PutStr("receiver_type", rType)
}

for rType, count := range eR.LogsReceiverCountsByType {
point := dataPoints.AppendEmpty()
point.SetIntValue(int64(count))
attributes := point.Attributes()
attributes.PutStr("telemetry_type", "logs")
attributes.PutStr("receiver_type", rType)
}

jsonMarshaler := &pmetric.JSONMarshaler{}
json, err := jsonMarshaler.MarshalMetrics(metrics)
if err != nil {
return err
}

err = os.WriteFile(enabledReceiversOTLPJSONFilePath, json, 0644)
if err != nil {
return err
}

return nil
}

func CollectFeatureTrackingMetricToOTLPJSON(ctx context.Context, uc *confgenerator.UnifiedConfig) error {
features, err := confgenerator.ExtractFeatures(ctx, uc)

Check failure on line 302 in internal/self_metrics/self_metrics.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

not enough arguments in call to confgenerator.ExtractFeatures

Check failure on line 302 in internal/self_metrics/self_metrics.go

View workflow job for this annotation

GitHub Actions / test (windows-latest)

not enough arguments in call to confgenerator.ExtractFeatures

Check failure on line 302 in internal/self_metrics/self_metrics.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

not enough arguments in call to confgenerator.ExtractFeatures

Check failure on line 302 in internal/self_metrics/self_metrics.go

View workflow job for this annotation

GitHub Actions / test (windows-latest)

not enough arguments in call to confgenerator.ExtractFeatures
if err != nil {
return err
}

metrics := pmetric.NewMetrics()
gaugeMetric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
gaugeMetric.SetName(getFullAgentMetricName(featureTrackingMetricName))
dataPoints := gaugeMetric.SetEmptyGauge().DataPoints()

for _, f := range features {
point := dataPoints.AppendEmpty()
point.SetIntValue(int64(1))
attributes := point.Attributes()
attributes.PutStr("module", f.Module)
attributes.PutStr("feature", fmt.Sprintf("%s:%s", f.Kind, f.Type))
attributes.PutStr("key", strings.Join(f.Key, "."))
attributes.PutStr("value", f.Value)
}

jsonMarshaler := &pmetric.JSONMarshaler{}
json, err := jsonMarshaler.MarshalMetrics(metrics)
if err != nil {
return err
}

err = os.WriteFile(featureTrackingOTLPJSONFilePath, json, 0644)
if err != nil {
return err
}

return nil
}

func CollectOpsAgentSelfMetricsToOTLPJSON(ctx context.Context, userUc, mergedUc *confgenerator.UnifiedConfig) (err error) {
err = CollectFeatureTrackingMetricToOTLPJSON(ctx, userUc)
if err != nil {
return fmt.Errorf("failed to collect feature tracking metric to otlp json: %w", err)
}

err = CollectEnabledReceiversMetricToOLTPJSON(ctx, mergedUc)
if err != nil {
return fmt.Errorf("failed to collect enabled receivers metric to otlp json: %w", err)
}
return nil
}

0 comments on commit 63ebf59

Please sign in to comment.