Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f1bc179
Initial Implementation of global knob for otlp_exporter
rafaelwestphal May 6, 2026
149c203
Fix Windows compilation and UAP plugin tests for health checks refact…
rafaelwestphal May 6, 2026
eeda003
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal May 6, 2026
6d204ed
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal May 13, 2026
32a833d
Update goldens for otlp_exporter_global_config after merging master
rafaelwestphal May 13, 2026
9e476c9
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal May 15, 2026
0f2ad89
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal May 15, 2026
bdd0aa4
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal May 16, 2026
3087f88
Update goldens for otlp_exporter_global_config after merging master
rafaelwestphal May 16, 2026
078dd45
Address PR #2292 code review comments
rafaelwestphal May 21, 2026
ef051c9
Fix healthcheck OTLP exporter check and decouple from experiments
rafaelwestphal May 21, 2026
c7fb0ed
Remove extra blank line from test-otlp-exporter-only/input.yaml
rafaelwestphal May 21, 2026
03c1060
Remove rogue empty lines from various test input.yaml files
rafaelwestphal May 21, 2026
7d6b575
Assimilate shared context keys into internal/experiments package
rafaelwestphal May 21, 2026
8901d4a
Simplify health check design and remove unnecessary context passing
rafaelwestphal May 22, 2026
e02348b
Revert redundant ContextWithExperiments calls and experiments.go styling
rafaelwestphal May 22, 2026
bd5ccef
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal May 22, 2026
a6801d6
Update goldens for otlp_exporter_global_config after merging master
rafaelwestphal May 22, 2026
9a3e332
Fix Windows compilation and test errors after health check refactoring
rafaelwestphal May 22, 2026
57751e2
Remove dead ContextWithExperiments call in service_windows.go Start
rafaelwestphal May 22, 2026
52fd3da
Decouple OTLP exporter from context and implement post-processing con…
rafaelwestphal May 25, 2026
6e2653e
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob a…
rafaelwestphal May 25, 2026
01aac52
Format imports in config.go to satisfy gci linter
rafaelwestphal May 25, 2026
d9915cd
Fix config.go formatting to satisfy golangci-lint (gci)
rafaelwestphal May 25, 2026
bd0ab0e
Merge master into westphalrafael/otlp_exporter_config_knob and resolv…
rafaelwestphal Jun 10, 2026
0cd6255
Fix non-constant format string errors in integration_test/agents
rafaelwestphal Jun 10, 2026
ab4dbac
Merge branch 'master' into westphalrafael/otlp_exporter_config_knob
rafaelwestphal Jun 10, 2026
4b7407c
otlp: switch to UTR endpoint (#2186)
ridwanmsharif Jun 11, 2026
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
7 changes: 3 additions & 4 deletions cmd/google_cloud_ops_agent_engine/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ var (
healthChecks = flag.Bool("healthchecks", false, "run health checks and exit")
)

func runHealthChecks() {
func runHealthChecks(otlpExporterEnabled bool) {
logger := healthchecks.CreateHealthChecksLogger(*logsDir)

defaultLogger := logs.NewSimpleLogger()

healthCheckResults := healthchecks.HealthCheckRegistryFactory().RunAllHealthChecks(logger)
healthCheckResults := healthchecks.HealthCheckRegistryFactory(otlpExporterEnabled).RunAllHealthChecks(logger)
healthchecks.LogHealthCheckResults(healthCheckResults, defaultLogger)
}

Expand All @@ -59,7 +59,6 @@ func run() error {
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 All @@ -68,7 +67,7 @@ func run() error {

switch *service {
case "":
runHealthChecks()
runHealthChecks(uc.Global.GetOtlpExporter())
log.Println("Startup checks finished")
if *healthChecks {
// If healthchecks is set, stop here
Expand Down
4 changes: 2 additions & 2 deletions cmd/ops_agent_uap_plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ func writeCustomConfigToFile(req *pb.StartRequest, configPath string) error {
return nil
}

func runHealthChecks(healthCheckFileLogger logs.StructuredLogger) {
gceHealthChecks := healthchecks.HealthCheckRegistryFactory()
func runHealthChecks(healthCheckFileLogger logs.StructuredLogger, otlpExporterEnabled bool) {
gceHealthChecks := healthchecks.HealthCheckRegistryFactory(otlpExporterEnabled)

// Log health check results to health-checks.log log file.
gceHealthChecks.RunAllHealthChecks(healthCheckFileLogger)
Expand Down
10 changes: 5 additions & 5 deletions cmd/ops_agent_uap_plugin/service_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,15 @@ func (ps *OpsAgentPluginServer) Start(ctx context.Context, msg *pb.StartRequest)
}

// Ops Agent config validation
if err := validateOpsAgentConfig(pContext, OpsAgentConfigLocationLinux); err != nil {
uc, err := validateOpsAgentConfig(pContext, OpsAgentConfigLocationLinux)
if err != nil {
ps.cancelAndSetPluginError(&OpsAgentPluginError{Message: fmt.Sprintf("Start() failed to validate the custom Ops Agent config: %s", err), ShouldRestart: false})
return &pb.StartResponse{}, nil
}

// Trigger Healthchecks.
healthCheckFileLogger := healthchecks.CreateHealthChecksLogger(filepath.Join(pluginStateDir, LogsDirectory))
runHealthChecks(healthCheckFileLogger)
runHealthChecks(healthCheckFileLogger, uc.Global.GetOtlpExporter())

// Subagent config generation
if err := generateSubagentConfigs(pContext, ps.runCommand, pluginInstallDir, pluginStateDir); err != nil {
Expand Down Expand Up @@ -198,9 +199,8 @@ func runCommand(cmd *exec.Cmd) (string, error) {
return string(out), err
}

func validateOpsAgentConfig(ctx context.Context, opsAgentConfigLocation string) error {
_, err := confgenerator.MergeConfFiles(ctx, opsAgentConfigLocation)
return err
func validateOpsAgentConfig(ctx context.Context, opsAgentConfigLocation string) (*confgenerator.UnifiedConfig, error) {
return confgenerator.MergeConfFiles(ctx, opsAgentConfigLocation)
}

func generateSubagentConfigs(ctx context.Context, runCommand RunCommandFunc, pluginInstallDirectory string, pluginStateDirectory string) error {
Expand Down
2 changes: 1 addition & 1 deletion cmd/ops_agent_uap_plugin/service_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func Test_validateOpsAgentConfig(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
err := validateOpsAgentConfig(ctx, tc.path)
_, err := validateOpsAgentConfig(ctx, tc.path)
gotSuccess := (err == nil)
if gotSuccess != tc.wantSuccess {
t.Errorf("%s: validateOpsAgentConfig() got success = %v, want %v, error: %v", tc.name, gotSuccess, tc.wantSuccess, err)
Expand Down
15 changes: 8 additions & 7 deletions cmd/ops_agent_uap_plugin/service_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ func (ps *OpsAgentPluginServer) Start(ctx context.Context, msg *pb.StartRequest)
}

// Subagents config validation and generation.
if err := generateSubAgentConfigs(ctx, OpsAgentConfigLocationWindows, pluginStateDir); err != nil {
uc, err := generateSubAgentConfigs(ctx, OpsAgentConfigLocationWindows, pluginStateDir)
if err != nil {
ps.cancelAndSetPluginError(&OpsAgentPluginError{
Message: fmt.Sprintf("Start() failed to validate the custom Ops Agent config, and generate sub-agents config: %s", err),
ShouldRestart: false,
Expand All @@ -121,7 +122,7 @@ func (ps *OpsAgentPluginServer) Start(ctx context.Context, msg *pb.StartRequest)

// Trigger Healthchecks.
healthCheckFileLogger := healthchecks.CreateHealthChecksLogger(filepath.Join(pluginStateDir, LogsDirectory))
runHealthChecks(healthCheckFileLogger)
runHealthChecks(healthCheckFileLogger, uc.Global.GetOtlpExporter())

// Create a Windows Job object and stores its handle, to ensure that all child processes are killed when the parent process exits.
_, err = createWindowsJobHandle()
Expand Down Expand Up @@ -205,18 +206,18 @@ func findPreExistentAgents(mgr serviceManager, agentWindowsServiceNames []string
return alreadyInstalledAgentServiceNames, nil
}

func generateSubAgentConfigs(ctx context.Context, userConfigPath string, pluginStateDir string) error {
func generateSubAgentConfigs(ctx context.Context, userConfigPath string, pluginStateDir string) (*confgenerator.UnifiedConfig, error) {
uc, err := confgenerator.MergeConfFiles(ctx, userConfigPath)
if err != nil {
return err
return nil, err
}

log.Printf("Built-in config:\n%s\n", confgenerator.BuiltInConfStructs["windows"])
log.Printf("Merged config:\n%s\n", uc)

// The generated otlp metric json files are used only by the otel service.
if err = self_metrics.GenerateOpsAgentSelfMetricsOTLPJSON(ctx, userConfigPath, filepath.Join(pluginStateDir, GeneratedConfigsOutDir, "otel")); err != nil {
return err
return nil, err
}

for _, subagent := range []string{
Expand All @@ -229,10 +230,10 @@ func generateSubAgentConfigs(ctx context.Context, userConfigPath string, pluginS
filepath.Join(pluginStateDir, LogsDirectory),
filepath.Join(pluginStateDir, RuntimeDirectory),
filepath.Join(pluginStateDir, GeneratedConfigsOutDir, subagent)); err != nil {
return err
return nil, err
}
}
return nil
return uc, nil
}

func createWindowsJobHandle() (windows.Handle, error) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/ops_agent_uap_plugin/service_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func Test_runHealthChecks_LogFileNonEmpty(t *testing.T) {
defer os.Remove(healthCheckLogFile.Name())
mockHealthCheckLogger := &mockHealthCheckLogger{logFile: healthCheckLogFile}

runHealthChecks(mockHealthCheckLogger)
runHealthChecks(mockHealthCheckLogger, false)

// Check if the log file has content
fileInfo, err := os.Stat(healthCheckLogFile.Name())
Expand Down Expand Up @@ -204,7 +204,7 @@ func Test_generateSubAgentConfigs(t *testing.T) {
}
userConfigFile.Close()

err = generateSubAgentConfigs(ctx, userConfigFile.Name(), tc.pluginStateDir)
_, err = generateSubAgentConfigs(ctx, userConfigFile.Name(), tc.pluginStateDir)
if (err != nil) != tc.wantError {
t.Errorf("generateSubAgentConfigs() returned error: %v, want error: %v", err, tc.wantError)
}
Expand Down
17 changes: 16 additions & 1 deletion cmd/ops_agent_windows/main_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
package main

import (
"context"
"flag"
"fmt"
"log"
"os"
"path/filepath"

"github.com/GoogleCloudPlatform/ops-agent/confgenerator"
"github.com/GoogleCloudPlatform/ops-agent/internal/healthchecks"
"github.com/GoogleCloudPlatform/ops-agent/internal/logs"
"github.com/kardianos/osext"
Expand Down Expand Up @@ -63,7 +65,20 @@ func main() {
}
infoLog.Printf("uninstalled services")
} else if *healthChecks {
healthCheckResults := getHealthCheckResults()
ctx := context.Background()
base, err := osext.ExecutableFolder()
if err != nil {
log.Fatalf("failed to determine executable folder: %v", err)
}
configPath := filepath.Join(base, "../config/config.yaml")
otlpExporterEnabled := false
uc, err := confgenerator.MergeConfFiles(ctx, configPath)
if err == nil {
otlpExporterEnabled = uc.Global.GetOtlpExporter()
} else {
log.Printf("failed to load config: %v", err)
}
healthCheckResults := getHealthCheckResults(otlpExporterEnabled)
healthchecks.LogHealthCheckResults(healthCheckResults, infoLog)
infoLog.Println("Health checks finished")
} else {
Expand Down
8 changes: 5 additions & 3 deletions cmd/ops_agent_windows/run_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type service struct {
log debug.Log
userConf string
outDirectory string
uc *confgenerator.UnifiedConfig
}

func (s *service) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
Expand Down Expand Up @@ -141,16 +142,16 @@ func (s *service) checkForStandaloneAgents(unified *confgenerator.UnifiedConfig)
return nil
}

func getHealthCheckResults() []healthchecks.HealthCheckResult {
func getHealthCheckResults(otlpExporterEnabled bool) []healthchecks.HealthCheckResult {
logsDir := filepath.Join(os.Getenv("PROGRAMDATA"), dataDirectory, "log")
gceHealthChecks := healthchecks.HealthCheckRegistryFactory()
gceHealthChecks := healthchecks.HealthCheckRegistryFactory(otlpExporterEnabled)
logger := healthchecks.CreateHealthChecksLogger(logsDir)

return gceHealthChecks.RunAllHealthChecks(logger)
}

func (srv *service) runHealthChecks() {
healthCheckResults := getHealthCheckResults()
healthCheckResults := getHealthCheckResults(srv.uc.Global.GetOtlpExporter())
logger := logs.WindowsServiceLogger{EventID: EngineEventID, Logger: srv.log}
healthchecks.LogHealthCheckResults(healthCheckResults, logger)
srv.log.Info(EngineEventID, "Startup checks finished")
Expand All @@ -162,6 +163,7 @@ func (s *service) generateConfigs(ctx context.Context) error {
if err != nil {
return err
}
s.uc = uc

s.log.Info(EngineEventID, fmt.Sprintf("Built-in config:\n%s\n", confgenerator.BuiltInConfStructs["windows"]))
s.log.Info(EngineEventID, fmt.Sprintf("Merged config:\n%s\n", uc))
Expand Down
6 changes: 3 additions & 3 deletions confgenerator/agentmetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (

"github.com/GoogleCloudPlatform/ops-agent/confgenerator/otel"
"github.com/GoogleCloudPlatform/ops-agent/confgenerator/otel/ottl"
"github.com/GoogleCloudPlatform/ops-agent/internal/experiments"
)

// AgentSelfMetrics provides the agent.googleapis.com/agent/ metrics.
Expand All @@ -34,6 +33,7 @@ type AgentSelfMetrics struct {
FluentBitPort int
OtelPort int
OtelRuntimeDir string
OtlpExporterEnabled bool
}

// Following reference : https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
Expand Down Expand Up @@ -182,7 +182,7 @@ func (r AgentSelfMetrics) OtelPipelineProcessors(ctx context.Context) []otel.Com
`metric.name == "` + durationCountMetric + `" and (not IsMatch(datapoint.attributes["grpc.target"], "monitoring.googleapis"))`,
})

expOtlpExporter := experiments.FromContext(ctx)["otlp_exporter"]
expOtlpExporter := r.OtlpExporterEnabled
var extraTransforms []map[string]interface{}
if expOtlpExporter {
durationMetric = "rpc.client.call.duration"
Expand Down Expand Up @@ -293,7 +293,7 @@ func (r AgentSelfMetrics) LoggingMetricsPipelineProcessors(ctx context.Context)
otel.AggregateLabels("sum", "response_code"),
)

expOtlpExporter := experiments.FromContext(ctx)["otlp_exporter"]
expOtlpExporter := r.OtlpExporterEnabled
if expOtlpExporter {
durationMetric = "rpc.client.call.duration"
durationCountMetric = "rpc.client.call.duration_count"
Expand Down
Loading
Loading