diff --git a/pkg/collector/corechecks/servicediscovery/events.go b/pkg/collector/corechecks/servicediscovery/events.go index 5cba3f89243ac..fba57253ad552 100644 --- a/pkg/collector/corechecks/servicediscovery/events.go +++ b/pkg/collector/corechecks/servicediscovery/events.go @@ -26,25 +26,26 @@ const ( ) type eventPayload struct { - NamingSchemaVersion string `json:"naming_schema_version"` - ServiceName string `json:"service_name"` - GeneratedServiceName string `json:"generated_service_name"` - DDService string `json:"dd_service,omitempty"` - HostName string `json:"host_name"` - Env string `json:"env"` - ServiceLanguage string `json:"service_language"` - ServiceType string `json:"service_type"` - StartTime int64 `json:"start_time"` - StartTimeMilli int64 `json:"start_time_milli"` - LastSeen int64 `json:"last_seen"` - APMInstrumentation string `json:"apm_instrumentation"` - ServiceNameSource string `json:"service_name_source,omitempty"` - Ports []uint16 `json:"ports"` - PID int `json:"pid"` - CommandLine []string `json:"command_line"` - RSSMemory uint64 `json:"rss_memory"` - CPUCores float64 `json:"cpu_cores"` - ContainerID string `json:"container_id"` + NamingSchemaVersion string `json:"naming_schema_version"` + ServiceName string `json:"service_name"` + GeneratedServiceName string `json:"generated_service_name"` + GeneratedServiceNameSource string `json:"generated_service_name_source,omitempty"` + DDService string `json:"dd_service,omitempty"` + HostName string `json:"host_name"` + Env string `json:"env"` + ServiceLanguage string `json:"service_language"` + ServiceType string `json:"service_type"` + StartTime int64 `json:"start_time"` + StartTimeMilli int64 `json:"start_time_milli"` + LastSeen int64 `json:"last_seen"` + APMInstrumentation string `json:"apm_instrumentation"` + ServiceNameSource string `json:"service_name_source,omitempty"` + Ports []uint16 `json:"ports"` + PID int `json:"pid"` + CommandLine []string `json:"command_line"` + RSSMemory uint64 `json:"rss_memory"` + CPUCores float64 `json:"cpu_cores"` + ContainerID string `json:"container_id"` } type event struct { @@ -74,25 +75,26 @@ func (ts *telemetrySender) newEvent(t eventType, svc serviceInfo) *event { RequestType: t, APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: svc.meta.Name, - GeneratedServiceName: svc.service.GeneratedName, - DDService: svc.service.DDService, - HostName: host, - Env: env, - ServiceLanguage: svc.meta.Language, - ServiceType: svc.meta.Type, - StartTime: int64(svc.service.StartTimeMilli / 1000), - StartTimeMilli: int64(svc.service.StartTimeMilli), - LastSeen: svc.LastHeartbeat.Unix(), - APMInstrumentation: svc.meta.APMInstrumentation, - ServiceNameSource: nameSource, - Ports: svc.service.Ports, - PID: svc.service.PID, - CommandLine: svc.service.CommandLine, - RSSMemory: svc.service.RSS, - CPUCores: svc.service.CPUCores, - ContainerID: svc.service.ContainerID, + NamingSchemaVersion: "1", + ServiceName: svc.meta.Name, + GeneratedServiceName: svc.service.GeneratedName, + GeneratedServiceNameSource: svc.service.GeneratedNameSource, + DDService: svc.service.DDService, + HostName: host, + Env: env, + ServiceLanguage: svc.meta.Language, + ServiceType: svc.meta.Type, + StartTime: int64(svc.service.StartTimeMilli / 1000), + StartTimeMilli: int64(svc.service.StartTimeMilli), + LastSeen: svc.LastHeartbeat.Unix(), + APMInstrumentation: svc.meta.APMInstrumentation, + ServiceNameSource: nameSource, + Ports: svc.service.Ports, + PID: svc.service.PID, + CommandLine: svc.service.CommandLine, + RSSMemory: svc.service.RSS, + CPUCores: svc.service.CPUCores, + ContainerID: svc.service.ContainerID, }, } } diff --git a/pkg/collector/corechecks/servicediscovery/events_test.go b/pkg/collector/corechecks/servicediscovery/events_test.go index 6974ae4c138a8..f8b7fc92bcfb3 100644 --- a/pkg/collector/corechecks/servicediscovery/events_test.go +++ b/pkg/collector/corechecks/servicediscovery/events_test.go @@ -56,16 +56,17 @@ func Test_telemetrySender(t *testing.T) { svc := serviceInfo{ service: model.Service{ - PID: 99, - CommandLine: []string{"test-service", "--args"}, - Ports: []uint16{80, 8080}, - StartTimeMilli: uint64(now.Add(-20 * time.Minute).UnixMilli()), - RSS: 500 * 1024 * 1024, - GeneratedName: "generated-name", - DDService: "dd-service", - DDServiceInjected: true, - CPUCores: 1.5, - ContainerID: "abcd", + PID: 99, + CommandLine: []string{"test-service", "--args"}, + Ports: []uint16{80, 8080}, + StartTimeMilli: uint64(now.Add(-20 * time.Minute).UnixMilli()), + RSS: 500 * 1024 * 1024, + GeneratedName: "generated-name", + GeneratedNameSource: "generated-name-source", + DDService: "dd-service", + DDServiceInjected: true, + CPUCores: 1.5, + ContainerID: "abcd", }, meta: ServiceMetadata{ Name: "test-service", @@ -85,75 +86,78 @@ func Test_telemetrySender(t *testing.T) { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service", - GeneratedServiceName: "generated-name", - DDService: "dd-service", - ServiceNameSource: "injected", - HostName: "test-host", - Env: "", - ServiceLanguage: "jvm", - ServiceType: "web_service", - StartTime: 1715557200, - StartTimeMilli: 1715557200 * 1000, - LastSeen: 1715558400, - APMInstrumentation: "injected", - Ports: []uint16{80, 8080}, - PID: 99, - CommandLine: []string{"test-service", "--args"}, - RSSMemory: 500 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: "abcd", + NamingSchemaVersion: "1", + ServiceName: "test-service", + GeneratedServiceName: "generated-name", + GeneratedServiceNameSource: "generated-name-source", + DDService: "dd-service", + ServiceNameSource: "injected", + HostName: "test-host", + Env: "", + ServiceLanguage: "jvm", + ServiceType: "web_service", + StartTime: 1715557200, + StartTimeMilli: 1715557200 * 1000, + LastSeen: 1715558400, + APMInstrumentation: "injected", + Ports: []uint16{80, 8080}, + PID: 99, + CommandLine: []string{"test-service", "--args"}, + RSSMemory: 500 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: "abcd", }, }, { RequestType: "heartbeat-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service", - GeneratedServiceName: "generated-name", - DDService: "dd-service", - ServiceNameSource: "injected", - HostName: "test-host", - Env: "", - ServiceLanguage: "jvm", - ServiceType: "web_service", - StartTime: 1715557200, - StartTimeMilli: 1715557200 * 1000, - LastSeen: 1715558400, - APMInstrumentation: "injected", - Ports: []uint16{80, 8080}, - PID: 99, - CommandLine: []string{"test-service", "--args"}, - RSSMemory: 500 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: "abcd", + NamingSchemaVersion: "1", + ServiceName: "test-service", + GeneratedServiceName: "generated-name", + GeneratedServiceNameSource: "generated-name-source", + DDService: "dd-service", + ServiceNameSource: "injected", + HostName: "test-host", + Env: "", + ServiceLanguage: "jvm", + ServiceType: "web_service", + StartTime: 1715557200, + StartTimeMilli: 1715557200 * 1000, + LastSeen: 1715558400, + APMInstrumentation: "injected", + Ports: []uint16{80, 8080}, + PID: 99, + CommandLine: []string{"test-service", "--args"}, + RSSMemory: 500 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: "abcd", }, }, { RequestType: "end-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service", - GeneratedServiceName: "generated-name", - DDService: "dd-service", - ServiceNameSource: "injected", - HostName: "test-host", - Env: "", - ServiceLanguage: "jvm", - ServiceType: "web_service", - StartTime: 1715557200, - StartTimeMilli: 1715557200 * 1000, - LastSeen: 1715558400, - APMInstrumentation: "injected", - Ports: []uint16{80, 8080}, - PID: 99, - CommandLine: []string{"test-service", "--args"}, - RSSMemory: 500 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: "abcd", + NamingSchemaVersion: "1", + ServiceName: "test-service", + GeneratedServiceName: "generated-name", + GeneratedServiceNameSource: "generated-name-source", + DDService: "dd-service", + ServiceNameSource: "injected", + HostName: "test-host", + Env: "", + ServiceLanguage: "jvm", + ServiceType: "web_service", + StartTime: 1715557200, + StartTimeMilli: 1715557200 * 1000, + LastSeen: 1715558400, + APMInstrumentation: "injected", + Ports: []uint16{80, 8080}, + PID: 99, + CommandLine: []string{"test-service", "--args"}, + RSSMemory: 500 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: "abcd", }, }, } @@ -184,12 +188,13 @@ func Test_telemetrySender_name_provided(t *testing.T) { svc := serviceInfo{ service: model.Service{ - PID: 55, - CommandLine: []string{"foo", "--option"}, - StartTimeMilli: uint64(now.Add(-20 * time.Minute).UnixMilli()), - GeneratedName: "generated-name2", - DDService: "dd-service-provided", - ContainerID: "abcd", + PID: 55, + CommandLine: []string{"foo", "--option"}, + StartTimeMilli: uint64(now.Add(-20 * time.Minute).UnixMilli()), + GeneratedName: "generated-name2", + GeneratedNameSource: "generated-name-source2", + DDService: "dd-service-provided", + ContainerID: "abcd", }, meta: ServiceMetadata{ Name: "test-service", @@ -209,66 +214,69 @@ func Test_telemetrySender_name_provided(t *testing.T) { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service", - GeneratedServiceName: "generated-name2", - DDService: "dd-service-provided", - ServiceNameSource: "provided", - HostName: "test-host", - Env: "", - ServiceLanguage: "jvm", - ServiceType: "web_service", - StartTime: 1715557200, - StartTimeMilli: 1715557200 * 1000, - LastSeen: 1715558400, - APMInstrumentation: "injected", - PID: 55, - CommandLine: []string{"foo", "--option"}, - ContainerID: "abcd", + NamingSchemaVersion: "1", + ServiceName: "test-service", + GeneratedServiceName: "generated-name2", + GeneratedServiceNameSource: "generated-name-source2", + DDService: "dd-service-provided", + ServiceNameSource: "provided", + HostName: "test-host", + Env: "", + ServiceLanguage: "jvm", + ServiceType: "web_service", + StartTime: 1715557200, + StartTimeMilli: 1715557200 * 1000, + LastSeen: 1715558400, + APMInstrumentation: "injected", + PID: 55, + CommandLine: []string{"foo", "--option"}, + ContainerID: "abcd", }, }, { RequestType: "heartbeat-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service", - GeneratedServiceName: "generated-name2", - DDService: "dd-service-provided", - ServiceNameSource: "provided", - HostName: "test-host", - Env: "", - ServiceLanguage: "jvm", - ServiceType: "web_service", - StartTime: 1715557200, - StartTimeMilli: 1715557200 * 1000, - LastSeen: 1715558400, - APMInstrumentation: "injected", - PID: 55, - CommandLine: []string{"foo", "--option"}, - ContainerID: "abcd", + NamingSchemaVersion: "1", + ServiceName: "test-service", + GeneratedServiceName: "generated-name2", + GeneratedServiceNameSource: "generated-name-source2", + DDService: "dd-service-provided", + ServiceNameSource: "provided", + HostName: "test-host", + Env: "", + ServiceLanguage: "jvm", + ServiceType: "web_service", + StartTime: 1715557200, + StartTimeMilli: 1715557200 * 1000, + LastSeen: 1715558400, + APMInstrumentation: "injected", + PID: 55, + CommandLine: []string{"foo", "--option"}, + ContainerID: "abcd", }, }, { RequestType: "end-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service", - GeneratedServiceName: "generated-name2", - DDService: "dd-service-provided", - ServiceNameSource: "provided", - HostName: "test-host", - Env: "", - ServiceLanguage: "jvm", - ServiceType: "web_service", - StartTime: 1715557200, - StartTimeMilli: 1715557200 * 1000, - LastSeen: 1715558400, - APMInstrumentation: "injected", - PID: 55, - CommandLine: []string{"foo", "--option"}, - ContainerID: "abcd", + NamingSchemaVersion: "1", + ServiceName: "test-service", + GeneratedServiceName: "generated-name2", + GeneratedServiceNameSource: "generated-name-source2", + DDService: "dd-service-provided", + ServiceNameSource: "provided", + HostName: "test-host", + Env: "", + ServiceLanguage: "jvm", + ServiceType: "web_service", + StartTime: 1715557200, + StartTimeMilli: 1715557200 * 1000, + LastSeen: 1715558400, + APMInstrumentation: "injected", + PID: 55, + CommandLine: []string{"foo", "--option"}, + ContainerID: "abcd", }, }, } diff --git a/pkg/collector/corechecks/servicediscovery/impl_linux_test.go b/pkg/collector/corechecks/servicediscovery/impl_linux_test.go index b2ae5d1d4f962..f3f7d4baaeb66 100644 --- a/pkg/collector/corechecks/servicediscovery/impl_linux_test.go +++ b/pkg/collector/corechecks/servicediscovery/impl_linux_test.go @@ -72,44 +72,47 @@ var ( var ( portTCP8080 = model.Service{ - PID: procTestService1.pid, - Name: "test-service-1", - GeneratedName: "test-service-1-generated", - DDService: "test-service-1", - DDServiceInjected: true, - Ports: []uint16{8080}, - APMInstrumentation: string(apm.None), - RSS: 100 * 1024 * 1024, - CPUCores: 1.5, - CommandLine: []string{"test-service-1"}, - StartTimeMilli: procLaunchedMilli, - ContainerID: dummyContainerID, + PID: procTestService1.pid, + Name: "test-service-1", + GeneratedName: "test-service-1-generated", + GeneratedNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + DDServiceInjected: true, + Ports: []uint16{8080}, + APMInstrumentation: string(apm.None), + RSS: 100 * 1024 * 1024, + CPUCores: 1.5, + CommandLine: []string{"test-service-1"}, + StartTimeMilli: procLaunchedMilli, + ContainerID: dummyContainerID, } portTCP8080UpdatedRSS = model.Service{ - PID: procTestService1.pid, - Name: "test-service-1", - GeneratedName: "test-service-1-generated", - DDService: "test-service-1", - DDServiceInjected: true, - Ports: []uint16{8080}, - APMInstrumentation: string(apm.None), - RSS: 200 * 1024 * 1024, - CPUCores: 1.5, - CommandLine: []string{"test-service-1"}, - StartTimeMilli: procLaunchedMilli, - ContainerID: dummyContainerID, + PID: procTestService1.pid, + Name: "test-service-1", + GeneratedName: "test-service-1-generated", + GeneratedNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + DDServiceInjected: true, + Ports: []uint16{8080}, + APMInstrumentation: string(apm.None), + RSS: 200 * 1024 * 1024, + CPUCores: 1.5, + CommandLine: []string{"test-service-1"}, + StartTimeMilli: procLaunchedMilli, + ContainerID: dummyContainerID, } portTCP8080DifferentPID = model.Service{ - PID: procTestService1DifferentPID.pid, - Name: "test-service-1", - GeneratedName: "test-service-1-generated", - DDService: "test-service-1", - DDServiceInjected: true, - Ports: []uint16{8080}, - APMInstrumentation: string(apm.Injected), - CommandLine: []string{"test-service-1"}, - StartTimeMilli: procLaunchedMilli, - ContainerID: dummyContainerID, + PID: procTestService1DifferentPID.pid, + Name: "test-service-1", + GeneratedName: "test-service-1-generated", + GeneratedNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + DDServiceInjected: true, + Ports: []uint16{8080}, + APMInstrumentation: string(apm.Injected), + CommandLine: []string{"test-service-1"}, + StartTimeMilli: procLaunchedMilli, + ContainerID: dummyContainerID, } portTCP8081 = model.Service{ PID: procIgnoreService1.pid, @@ -120,23 +123,25 @@ var ( ContainerID: dummyContainerID, } portTCP5000 = model.Service{ - PID: procPythonService.pid, - Name: "python-service", - GeneratedName: "python-service", - Language: "python", - Ports: []uint16{5000}, - CommandLine: pythonCommandLine, - StartTimeMilli: procLaunchedMilli, - ContainerID: dummyContainerID, + PID: procPythonService.pid, + Name: "python-service", + GeneratedName: "python-service", + GeneratedNameSource: "python-service-source", + Language: "python", + Ports: []uint16{5000}, + CommandLine: pythonCommandLine, + StartTimeMilli: procLaunchedMilli, + ContainerID: dummyContainerID, } portTCP5432 = model.Service{ - PID: procTestService1Repeat.pid, - Name: "test-service-1", - GeneratedName: "test-service-1", - Ports: []uint16{5432}, - CommandLine: []string{"test-service-1"}, - StartTimeMilli: procLaunchedMilli, - ContainerID: dummyContainerID, + PID: procTestService1Repeat.pid, + Name: "test-service-1", + GeneratedName: "test-service-1", + GeneratedNameSource: "test-service-1-generated-source", + Ports: []uint16{5432}, + CommandLine: []string{"test-service-1"}, + StartTimeMilli: procLaunchedMilli, + ContainerID: dummyContainerID, } ) @@ -227,112 +232,117 @@ func Test_linuxImpl(t *testing.T) { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(1 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 99, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "none", - RSSMemory: 100 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(1 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 99, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + RSSMemory: 100 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: dummyContainerID, }, }, { RequestType: "heartbeat-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(20 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 99, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "none", - RSSMemory: 200 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(20 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 99, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + RSSMemory: 200 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: dummyContainerID, }, }, { RequestType: "end-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(20 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 99, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "none", - RSSMemory: 200 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(20 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 99, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + RSSMemory: 200 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: dummyContainerID, }, }, { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "python-service", - GeneratedServiceName: "python-service", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(1 * time.Minute).Unix(), - Ports: []uint16{5000}, - PID: 500, - ServiceLanguage: "python", - CommandLine: pythonCommandLine, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "python-service", + GeneratedServiceName: "python-service", + GeneratedServiceNameSource: "python-service-source", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(1 * time.Minute).Unix(), + Ports: []uint16{5000}, + PID: 500, + ServiceLanguage: "python", + CommandLine: pythonCommandLine, + ContainerID: dummyContainerID, }, }, { RequestType: "heartbeat-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "python-service", - GeneratedServiceName: "python-service", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(20 * time.Minute).Unix(), - Ports: []uint16{5000}, - PID: 500, - ServiceLanguage: "python", - CommandLine: pythonCommandLine, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "python-service", + GeneratedServiceName: "python-service", + GeneratedServiceNameSource: "python-service-source", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(20 * time.Minute).Unix(), + Ports: []uint16{5000}, + PID: 500, + ServiceLanguage: "python", + CommandLine: pythonCommandLine, + ContainerID: dummyContainerID, }, }, }, @@ -376,105 +386,110 @@ func Test_linuxImpl(t *testing.T) { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1", - ServiceType: "db", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(1 * time.Minute).Unix(), - Ports: []uint16{5432}, - PID: 101, - CommandLine: []string{"test-service-1"}, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1", + GeneratedServiceNameSource: "test-service-1-generated-source", + ServiceType: "db", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(1 * time.Minute).Unix(), + Ports: []uint16{5432}, + PID: 101, + CommandLine: []string{"test-service-1"}, + ContainerID: dummyContainerID, }, }, { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(1 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 99, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "none", - RSSMemory: 100 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(1 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 99, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + RSSMemory: 100 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: dummyContainerID, }, }, { RequestType: "heartbeat-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1", - ServiceType: "db", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(20 * time.Minute).Unix(), - Ports: []uint16{5432}, - PID: 101, - CommandLine: []string{"test-service-1"}, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1", + GeneratedServiceNameSource: "test-service-1-generated-source", + ServiceType: "db", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(20 * time.Minute).Unix(), + Ports: []uint16{5432}, + PID: 101, + CommandLine: []string{"test-service-1"}, + ContainerID: dummyContainerID, }, }, { RequestType: "end-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1", - ServiceType: "db", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(20 * time.Minute).Unix(), - Ports: []uint16{5432}, - PID: 101, - CommandLine: []string{"test-service-1"}, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1", + GeneratedServiceNameSource: "test-service-1-generated-source", + ServiceType: "db", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(20 * time.Minute).Unix(), + Ports: []uint16{5432}, + PID: 101, + CommandLine: []string{"test-service-1"}, + ContainerID: dummyContainerID, }, }, { RequestType: "heartbeat-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(20 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 99, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "none", - RSSMemory: 100 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(20 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 99, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + RSSMemory: 100 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: dummyContainerID, }, }, }, @@ -516,46 +531,48 @@ func Test_linuxImpl(t *testing.T) { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(1 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 99, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "none", - RSSMemory: 100 * 1024 * 1024, - CPUCores: 1.5, - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(1 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 99, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + RSSMemory: 100 * 1024 * 1024, + CPUCores: 1.5, + ContainerID: dummyContainerID, }, }, { RequestType: "start-service", APIVersion: "v2", Payload: &eventPayload{ - NamingSchemaVersion: "1", - ServiceName: "test-service-1", - GeneratedServiceName: "test-service-1-generated", - DDService: "test-service-1", - ServiceNameSource: "injected", - ServiceType: "web_service", - HostName: host, - Env: "", - StartTime: calcTime(0).Unix(), - StartTimeMilli: calcTime(0).UnixMilli(), - LastSeen: calcTime(22 * time.Minute).Unix(), - Ports: []uint16{8080}, - PID: 102, - CommandLine: []string{"test-service-1"}, - APMInstrumentation: "injected", - ContainerID: dummyContainerID, + NamingSchemaVersion: "1", + ServiceName: "test-service-1", + GeneratedServiceName: "test-service-1-generated", + GeneratedServiceNameSource: "test-service-1-generated-source", + DDService: "test-service-1", + ServiceNameSource: "injected", + ServiceType: "web_service", + HostName: host, + Env: "", + StartTime: calcTime(0).Unix(), + StartTimeMilli: calcTime(0).UnixMilli(), + LastSeen: calcTime(22 * time.Minute).Unix(), + Ports: []uint16{8080}, + PID: 102, + CommandLine: []string{"test-service-1"}, + APMInstrumentation: "injected", + ContainerID: dummyContainerID, }, }, }, diff --git a/pkg/collector/corechecks/servicediscovery/model/model.go b/pkg/collector/corechecks/servicediscovery/model/model.go index f45cbae150eb4..ccaa3fc2a961c 100644 --- a/pkg/collector/corechecks/servicediscovery/model/model.go +++ b/pkg/collector/corechecks/servicediscovery/model/model.go @@ -11,6 +11,7 @@ type Service struct { PID int `json:"pid"` Name string `json:"name"` GeneratedName string `json:"generated_name"` + GeneratedNameSource string `json:"generated_name_source"` DDService string `json:"dd_service"` DDServiceInjected bool `json:"dd_service_injected"` CheckedContainerData bool `json:"checked_container_data"` diff --git a/pkg/collector/corechecks/servicediscovery/module/impl_linux.go b/pkg/collector/corechecks/servicediscovery/module/impl_linux.go index 181c22b662aaa..df021490fdd4c 100644 --- a/pkg/collector/corechecks/servicediscovery/module/impl_linux.go +++ b/pkg/collector/corechecks/servicediscovery/module/impl_linux.go @@ -50,6 +50,7 @@ var _ module.Module = &discovery{} // endpoint. type serviceInfo struct { generatedName string + generatedNameSource string ddServiceName string ddServiceInjected bool checkedContainerData bool @@ -420,13 +421,14 @@ func (s *discovery) getServiceInfo(proc *process.Process) (*serviceInfo, error) apmInstrumentation := apm.Detect(lang, ctx) return &serviceInfo{ - generatedName: nameMeta.Name, - ddServiceName: nameMeta.DDService, - language: lang, - apmInstrumentation: apmInstrumentation, - ddServiceInjected: nameMeta.DDServiceInjected, - cmdLine: sanitizeCmdLine(s.scrubber, cmdline), - startTimeMilli: uint64(createTime), + generatedName: nameMeta.Name, + generatedNameSource: string(nameMeta.Source), + ddServiceName: nameMeta.DDService, + language: lang, + apmInstrumentation: apmInstrumentation, + ddServiceInjected: nameMeta.DDServiceInjected, + cmdLine: sanitizeCmdLine(s.scrubber, cmdline), + startTimeMilli: uint64(createTime), }, nil } @@ -553,19 +555,19 @@ func (s *discovery) getService(context parsingContext, pid int32) *model.Service } return &model.Service{ - PID: int(pid), - Name: name, - GeneratedName: info.generatedName, - DDService: info.ddServiceName, - DDServiceInjected: info.ddServiceInjected, - CheckedContainerData: info.checkedContainerData, - Ports: ports, - APMInstrumentation: string(info.apmInstrumentation), - Language: string(info.language), - RSS: rss, - CommandLine: info.cmdLine, - StartTimeMilli: info.startTimeMilli, - CPUCores: info.cpuUsage, + PID: int(pid), + Name: name, + GeneratedName: info.generatedName, + GeneratedNameSource: info.generatedNameSource, + DDService: info.ddServiceName, + DDServiceInjected: info.ddServiceInjected, + Ports: ports, + APMInstrumentation: string(info.apmInstrumentation), + Language: string(info.language), + RSS: rss, + CommandLine: info.cmdLine, + StartTimeMilli: info.startTimeMilli, + CPUCores: info.cpuUsage, } } @@ -689,6 +691,7 @@ func (s *discovery) enrichContainerData(service *model.Service, containers map[s if service.DDService == "" { service.Name = serviceName } + service.GeneratedNameSource = string(usm.Container) } service.CheckedContainerData = true @@ -697,6 +700,7 @@ func (s *discovery) enrichContainerData(service *model.Service, containers map[s if ok { if serviceName != "" { serviceInfo.generatedName = serviceName + serviceInfo.generatedNameSource = string(usm.Container) } serviceInfo.checkedContainerData = true } diff --git a/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go b/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go index 81c5bdb6a9f3a..822e08866a0a1 100644 --- a/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go +++ b/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go @@ -47,6 +47,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/apm" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/model" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/usm" "github.com/DataDog/datadog-agent/pkg/network" "github.com/DataDog/datadog-agent/pkg/network/protocols/http/testutil" "github.com/DataDog/datadog-agent/pkg/network/protocols/tls/nodejs" @@ -367,6 +368,7 @@ func TestServiceName(t *testing.T) { assert.Equal(t, "foo_bar", portMap[pid].DDService) assert.Equal(t, portMap[pid].DDService, portMap[pid].Name) assert.Equal(t, "sleep", portMap[pid].GeneratedName) + assert.Equal(t, string(usm.CommandLine), portMap[pid].GeneratedNameSource) assert.False(t, portMap[pid].DDServiceInjected) assert.Equal(t, portMap[pid].ContainerID, "") }, 30*time.Second, 100*time.Millisecond) @@ -395,6 +397,7 @@ func TestInjectedServiceName(t *testing.T) { // The GeneratedName can vary depending on how the tests are run, so don't // assert for a specific value. require.NotEmpty(t, portMap[pid].GeneratedName) + require.NotEmpty(t, portMap[pid].GeneratedNameSource) require.NotEqual(t, portMap[pid].DDService, portMap[pid].GeneratedName) assert.True(t, portMap[pid].DDServiceInjected) } @@ -661,6 +664,7 @@ func TestNodeDocker(t *testing.T) { assert.Contains(collect, svcMap, pid) // test@... changed to test_... due to normalization. assert.Equal(collect, "test_nodejs-https-server", svcMap[pid].GeneratedName) + assert.Equal(collect, string(usm.Nodejs), svcMap[pid].GeneratedNameSource) assert.Equal(collect, svcMap[pid].GeneratedName, svcMap[pid].Name) assert.Equal(collect, "provided", svcMap[pid].APMInstrumentation) assertStat(collect, svcMap[pid]) @@ -842,6 +846,7 @@ func TestDocker(t *testing.T) { require.Contains(t, portMap[pid1111].ContainerID, "dummyCID") require.Contains(t, portMap[pid1111].Name, "foo_from_app_tag") require.Contains(t, portMap[pid1111].GeneratedName, "foo_from_app_tag") + require.Contains(t, portMap[pid1111].GeneratedNameSource, string(usm.Container)) } // Check that the cache is cleaned when procceses die. diff --git a/pkg/collector/corechecks/servicediscovery/usm/java.go b/pkg/collector/corechecks/servicediscovery/usm/java.go index 2102f8df7e720..bc8214bd3628f 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/java.go +++ b/pkg/collector/corechecks/servicediscovery/usm/java.go @@ -18,13 +18,19 @@ func newJavaDetector(ctx DetectionContext) detector { return &javaDetector{ctx: ctx} } +var vendorToSource = map[serverVendor]ServiceNameSource{ + tomcat: Tomcat, + weblogic: WebLogic, + websphere: WebSphere, + jboss: JBoss, +} + func (jd javaDetector) detect(args []string) (metadata ServiceMetadata, success bool) { // Look for dd.service if index := slices.IndexFunc(args, func(arg string) bool { return strings.HasPrefix(arg, "-Ddd.service=") }); index != -1 { metadata.DDService = strings.TrimPrefix(args[index], "-Ddd.service=") } prevArgIsFlag := false - var additionalNames []string for _, a := range args { hasFlagPrefix := strings.HasPrefix(a, "-") @@ -38,18 +44,30 @@ func (jd javaDetector) detect(args []string) (metadata ServiceMetadata, success if arg = trimColonRight(arg); isRuneLetterAt(arg, 0) { // do JEE detection to see if we can extract additional service names from context roots. - additionalNames = jeeExtractor(jd).extractServiceNamesForJEEServer() + vendor, additionalNames := jeeExtractor(jd).extractServiceNamesForJEEServer() + + source := CommandLine + if len(additionalNames) > 0 { + if vendorSource, ok := vendorToSource[vendor]; ok { + // The name gets joined to the AdditionalNames, so a part of + // the name still comes from the command line, but report + // the source as the web server since that is not easy to + // guess from looking at the command line. + source = vendorSource + } + } + if strings.HasSuffix(arg, javaJarExtension) || strings.HasSuffix(arg, javaWarExtension) { // try to see if the application is a spring boot archive and extract its application name if len(additionalNames) == 0 { if springAppName, ok := newSpringBootParser(jd.ctx).GetSpringBootAppName(a); ok { success = true - metadata.Name = springAppName + metadata.SetNames(springAppName, Spring) return } } success = true - metadata.SetNames(arg[:len(arg)-len(javaJarExtension)], additionalNames...) + metadata.SetNames(arg[:len(arg)-len(javaJarExtension)], source, additionalNames...) return } if strings.HasPrefix(arg, javaApachePrefix) { @@ -58,7 +76,7 @@ func (jd javaDetector) detect(args []string) (metadata ServiceMetadata, success arg = arg[len(javaApachePrefix):] if idx := strings.Index(arg, "."); idx != -1 { success = true - metadata.SetNames(arg[:idx], additionalNames...) + metadata.SetNames(arg[:idx], source, additionalNames...) return } } @@ -66,12 +84,12 @@ func (jd javaDetector) detect(args []string) (metadata ServiceMetadata, success if idx := strings.LastIndex(arg, "."); idx != -1 && idx+1 < len(arg) { // take just the class name without the package success = true - metadata.SetNames(arg[idx+1:], additionalNames...) + metadata.SetNames(arg[idx+1:], source, additionalNames...) return } success = true - metadata.SetNames(arg, additionalNames...) + metadata.SetNames(arg, source, additionalNames...) return } } diff --git a/pkg/collector/corechecks/servicediscovery/usm/jee.go b/pkg/collector/corechecks/servicediscovery/usm/jee.go index 8980a5ef42df1..62d5fe08a6c01 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/jee.go +++ b/pkg/collector/corechecks/servicediscovery/usm/jee.go @@ -297,19 +297,18 @@ func (je jeeExtractor) doExtractContextRoots(extractor vendorExtractor, app *jee return nil } -// extractServiceNamesForJEEServer takes args, cws and the fs (for testability reasons) and, after having determined the vendor, -// If the vendor can be determined, it returns the context roots if found, otherwise the server name. -// If the vendor is unknown, it returns a nil slice -func (je jeeExtractor) extractServiceNamesForJEEServer() []string { +// extractServiceNamesForJEEServer extracts the server vendor name and the +// service names from server-specific deployment files. +func (je jeeExtractor) extractServiceNamesForJEEServer() (serverVendor, []string) { vendor, domainHome := je.resolveAppServer() if vendor == unknown { - return nil + return vendor, nil } log.Debugf("running java enterprise service extraction - vendor %q", vendor) // check if able to find which applications are deployed extractorCreator, ok := extractors[vendor] if !ok { - return nil + return vendor, nil } extractor := extractorCreator(je.ctx) cwd, ok := workingDirFromEnvs(je.ctx.Envs) @@ -319,16 +318,16 @@ func (je jeeExtractor) extractServiceNamesForJEEServer() []string { apps, ok := extractor.findDeployedApps(domainHome) if !ok { - return nil + return vendor, nil } var contextRoots []string for _, app := range apps { contextRoots = append(contextRoots, normalizeContextRoot(je.doExtractContextRoots(extractor, &app)...)...) } if len(contextRoots) == 0 { - return nil + return vendor, nil } - return contextRoots + return vendor, contextRoots } func (s serverVendor) String() string { diff --git a/pkg/collector/corechecks/servicediscovery/usm/jee_test.go b/pkg/collector/corechecks/servicediscovery/usm/jee_test.go index 8da0f17ceea4c..792701947c459 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/jee_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/jee_test.go @@ -246,7 +246,8 @@ func TestWeblogicExtractServiceNamesForJEEServer(t *testing.T) { "PWD": "wls/domain", } extractor := jeeExtractor{ctx: NewDetectionContext(cmd, envs.NewVariables(envsMap), memfs)} - extractedContextRoots := extractor.extractServiceNamesForJEEServer() + vendor, extractedContextRoots := extractor.extractServiceNamesForJEEServer() + require.Equal(t, vendor, weblogic) require.Equal(t, []string{ "app1_context", // taken from ear application.xml "app2_context", // taken from war weblogic.xml diff --git a/pkg/collector/corechecks/servicediscovery/usm/nodejs.go b/pkg/collector/corechecks/servicediscovery/usm/nodejs.go index 5efb671327276..89e62bcf222e4 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/nodejs.go +++ b/pkg/collector/corechecks/servicediscovery/usm/nodejs.go @@ -62,14 +62,14 @@ func (n nodeDetector) detect(args []string) (ServiceMetadata, bool) { if _, err := fs.Stat(n.ctx.fs, absFile); err == nil { value, ok := n.findNameFromNearestPackageJSON(entryPoint) if ok { - return NewServiceMetadata(value), true + return NewServiceMetadata(value, Nodejs), true } // We couldn't find a package.json, fall back to the script/link // name since it should be better than just using "node". base := filepath.Base(absFile) name := strings.TrimSuffix(base, path.Ext(base)) - return NewServiceMetadata(name), true + return NewServiceMetadata(name, CommandLine), true } } } diff --git a/pkg/collector/corechecks/servicediscovery/usm/php.go b/pkg/collector/corechecks/servicediscovery/usm/php.go index e9e5c6b70f8de..c51d773034741 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/php.go +++ b/pkg/collector/corechecks/servicediscovery/usm/php.go @@ -40,7 +40,7 @@ func (p phpDetector) detect(args []string) (ServiceMetadata, bool) { if !prevArgIsFlag && !hasFlagPrefix { basePath := removeFilePath(arg) if isRuneLetterAt(basePath, 0) && basePath == artisanConsole { - metadata.SetNames(newLaravelParser(p.ctx).GetLaravelAppName(arg)) + metadata.SetNames(newLaravelParser(p.ctx).GetLaravelAppName(arg), Laravel) return metadata, true } } diff --git a/pkg/collector/corechecks/servicediscovery/usm/python.go b/pkg/collector/corechecks/servicediscovery/usm/python.go index 44b2c02309463..27dedaba9bf46 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/python.go +++ b/pkg/collector/corechecks/servicediscovery/usm/python.go @@ -56,7 +56,7 @@ func (p pythonDetector) detect(args []string) (ServiceMetadata, bool) { shouldSkipArg := prevArgIsFlag || hasFlagPrefix || isEnvVariable if moduleFlag { - return NewServiceMetadata(a), true + return NewServiceMetadata(a, CommandLine), true } if !shouldSkipArg { @@ -72,11 +72,11 @@ func (p pythonDetector) detect(args []string) (ServiceMetadata, bool) { stripped, filename = path.Split(stripped) // If the path is a root level file, return the filename if stripped == "" { - return NewServiceMetadata(p.findNearestTopLevel(filename)), true + return NewServiceMetadata(p.findNearestTopLevel(filename), CommandLine), true } } if value, ok := p.deducePackageName(path.Clean(stripped), filename); ok { - return NewServiceMetadata(value), true + return NewServiceMetadata(value, Python), true } name := p.findNearestTopLevel(stripped) @@ -85,7 +85,7 @@ func (p pythonDetector) detect(args []string) (ServiceMetadata, bool) { name = p.findNearestTopLevel(filename) } - return NewServiceMetadata(name), true + return NewServiceMetadata(name, CommandLine), true } if hasFlagPrefix && a == "-m" { @@ -142,20 +142,20 @@ func (g gunicornDetector) detect(args []string) (ServiceMetadata, bool) { if fromEnv, ok := extractEnvVar(g.ctx.Envs, gunicornEnvCmdArgs); ok { name, ok := extractGunicornNameFrom(strings.Split(fromEnv, " ")) if ok { - return NewServiceMetadata(name), true + return NewServiceMetadata(name, Gunicorn), true } } if wsgiApp, ok := extractEnvVar(g.ctx.Envs, wsgiAppEnv); ok && len(wsgiApp) > 0 { - return NewServiceMetadata(parseNameFromWsgiApp(wsgiApp)), true + return NewServiceMetadata(parseNameFromWsgiApp(wsgiApp), Gunicorn), true } if name, ok := extractGunicornNameFrom(args); ok { // gunicorn replaces the cmdline with something like "gunicorn: master // [package]", so strip out the square brackets. name = strings.Trim(name, "[]") - return NewServiceMetadata(name), true + return NewServiceMetadata(name, CommandLine), true } - return NewServiceMetadata("gunicorn"), true + return NewServiceMetadata("gunicorn", CommandLine), true } func extractGunicornNameFrom(args []string) (string, bool) { diff --git a/pkg/collector/corechecks/servicediscovery/usm/ruby.go b/pkg/collector/corechecks/servicediscovery/usm/ruby.go index 9c36d112ac99e..5404a1753d77d 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/ruby.go +++ b/pkg/collector/corechecks/servicediscovery/usm/ruby.go @@ -65,7 +65,7 @@ func (r railsDetector) detect(_ []string) (ServiceMetadata, bool) { return ServiceMetadata{}, false } - return NewServiceMetadata(string(name)), true + return NewServiceMetadata(string(name), Rails), true } // findRailsApplicationName scans the `config/application.rb` file to find the diff --git a/pkg/collector/corechecks/servicediscovery/usm/service.go b/pkg/collector/corechecks/servicediscovery/usm/service.go index da160aebada3f..407b77179dfb7 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/service.go +++ b/pkg/collector/corechecks/servicediscovery/usm/service.go @@ -51,19 +51,50 @@ const ( // ServiceMetadata holds information about a service. type ServiceMetadata struct { Name string + Source ServiceNameSource AdditionalNames []string DDService string DDServiceInjected bool // for future usage: we can detect also the type, vendor, frameworks, etc } +// ServiceNameSource is a string enum that represents the source of a generated service name +type ServiceNameSource string + +const ( + // CommandLine indicates that the name comes from the command line + CommandLine ServiceNameSource = "command-line" + // Container indicates the name comes from the container tags + Container ServiceNameSource = "container" + // Laravel indicates that the name comes from the Laravel application name + Laravel ServiceNameSource = "laravel" + // Python indicates that the name comes from the Python package name + Python ServiceNameSource = "python" + // Nodejs indicates that the name comes from the Node.js package name + Nodejs ServiceNameSource = "nodejs" + // Gunicorn indicates that the name comes from the Gunicorn application name + Gunicorn ServiceNameSource = "gunicorn" + // Rails indicates that the name comes from the Rails application name + Rails ServiceNameSource = "rails" + // Spring indicates that the name comes from the Spring application name + Spring ServiceNameSource = "spring" + // JBoss indicates that the name comes from the JBoss application name + JBoss ServiceNameSource = "jboss" + // Tomcat indicates that the name comes from the Tomcat application name + Tomcat ServiceNameSource = "tomcat" + // WebLogic indicates that the name comes from the WebLogic application name + WebLogic ServiceNameSource = "weblogic" + // WebSphere indicates that the name comes from the WebSphere application name + WebSphere ServiceNameSource = "websphere" +) + // NewServiceMetadata initializes ServiceMetadata. -func NewServiceMetadata(name string, additional ...string) ServiceMetadata { +func NewServiceMetadata(name string, source ServiceNameSource, additional ...string) ServiceMetadata { if len(additional) > 1 { // names are discovered in unpredictable order. We need to keep them sorted if we're going to join them slices.Sort(additional) } - return ServiceMetadata{Name: name, AdditionalNames: additional} + return ServiceMetadata{Name: name, Source: source, AdditionalNames: additional} } // SetAdditionalNames set additional names for the service @@ -76,8 +107,9 @@ func (s *ServiceMetadata) SetAdditionalNames(additional ...string) { } // SetNames sets generated names for the service. -func (s *ServiceMetadata) SetNames(name string, additional ...string) { +func (s *ServiceMetadata) SetNames(name string, source ServiceNameSource, additional ...string) { s.Name = name + s.Source = source s.SetAdditionalNames(additional...) } @@ -260,6 +292,7 @@ func ExtractServiceMetadata(lang language.Language, ctx DetectionContext) (metad if ok { metadata.Name = langMeta.Name + metadata.Source = langMeta.Source metadata.SetAdditionalNames(langMeta.AdditionalNames...) return } @@ -271,6 +304,7 @@ func ExtractServiceMetadata(lang language.Language, ctx DetectionContext) (metad } metadata.Name = exe + metadata.Source = CommandLine return } @@ -362,7 +396,7 @@ func (simpleDetector) detect(args []string) (ServiceMetadata, bool) { if !shouldSkipArg { if c := trimColonRight(removeFilePath(a)); isRuneLetterAt(c, 0) { - return NewServiceMetadata(c), true + return NewServiceMetadata(c, CommandLine), true } } @@ -381,7 +415,7 @@ func (dd dotnetDetector) detect(args []string) (ServiceMetadata, bool) { // https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-run#description if strings.HasSuffix(strings.ToLower(a), dllExtension) { file := removeFilePath(a) - return NewServiceMetadata(file[:len(file)-len(dllExtension)]), true + return NewServiceMetadata(file[:len(file)-len(dllExtension)], CommandLine), true } // dotnet cli syntax is something like `dotnet ` // if the first non arg (`-v, --something, ...) is not a dll file, exit early since nothing is matching a dll execute case diff --git a/pkg/collector/corechecks/servicediscovery/usm/service_test.go b/pkg/collector/corechecks/servicediscovery/usm/service_test.go index 9baa51f1780ff..8667662d64747 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/service_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/service_test.go @@ -49,16 +49,17 @@ func TestExtractServiceMetadata(t *testing.T) { require.NoError(t, err) subUsmTestData := NewSubDirFS(usmFull) tests := []struct { - name string - cmdline []string - envs map[string]string - lang language.Language - expectedGeneratedName string - expectedDDService string - expectedAdditionalServices []string - ddServiceInjected bool - fs *SubDirFS - skipOnWindows bool + name string + cmdline []string + envs map[string]string + lang language.Language + expectedGeneratedName string + expectedDDService string + expectedAdditionalServices []string + expectedGeneratedNameSource ServiceNameSource + ddServiceInjected bool + fs *SubDirFS + skipOnWindows bool }{ { name: "empty", @@ -75,116 +76,130 @@ func TestExtractServiceMetadata(t *testing.T) { cmdline: []string{ "./my-server.sh", }, - expectedGeneratedName: "my-server", + expectedGeneratedName: "my-server", + expectedGeneratedNameSource: CommandLine, }, { name: "single arg executable with DD_SERVICE", cmdline: []string{ "./my-server.sh", }, - envs: map[string]string{"DD_SERVICE": "my-service"}, - expectedDDService: "my-service", - expectedGeneratedName: "my-server", + envs: map[string]string{"DD_SERVICE": "my-service"}, + expectedDDService: "my-service", + expectedGeneratedName: "my-server", + expectedGeneratedNameSource: CommandLine, }, { name: "single arg executable with DD_TAGS", cmdline: []string{ "./my-server.sh", }, - envs: map[string]string{"DD_TAGS": "service:my-service"}, - expectedDDService: "my-service", - expectedGeneratedName: "my-server", + envs: map[string]string{"DD_TAGS": "service:my-service"}, + expectedDDService: "my-service", + expectedGeneratedName: "my-server", + expectedGeneratedNameSource: CommandLine, }, { name: "single arg executable with special chars", cmdline: []string{ "./-my-server.sh-", }, - expectedGeneratedName: "my-server", + expectedGeneratedName: "my-server", + expectedGeneratedNameSource: CommandLine, }, { name: "sudo", cmdline: []string{ "sudo", "-E", "-u", "dog", "/usr/local/bin/myApp", "-items=0,1,2,3", "-foo=bar", }, - expectedGeneratedName: "myApp", + expectedGeneratedName: "myApp", + expectedGeneratedNameSource: CommandLine, }, { name: "python flask argument", cmdline: []string{ "/opt/python/2.7.11/bin/python2.7", "flask", "run", "--host=0.0.0.0", }, - lang: language.Python, - expectedGeneratedName: "flask", - envs: map[string]string{"PWD": "testdata/python"}, - fs: &subUsmTestData, + lang: language.Python, + expectedGeneratedName: "flask", + expectedGeneratedNameSource: Python, + envs: map[string]string{"PWD": "testdata/python"}, + fs: &subUsmTestData, }, { name: "python - flask argument in path", cmdline: []string{ "/opt/python/2.7.11/bin/python2.7", "testdata/python/flask", "run", "--host=0.0.0.0", "--without-threads", }, - lang: language.Python, - expectedGeneratedName: "flask", - fs: &subUsmTestData, + lang: language.Python, + expectedGeneratedName: "flask", + expectedGeneratedNameSource: Python, + fs: &subUsmTestData, }, { name: "python flask in single argument", cmdline: []string{ "/opt/python/2.7.11/bin/python2.7 flask run --host=0.0.0.0", }, - lang: language.Python, - envs: map[string]string{"PWD": "testdata/python"}, - expectedGeneratedName: "flask", - fs: &subUsmTestData, + lang: language.Python, + envs: map[string]string{"PWD": "testdata/python"}, + expectedGeneratedName: "flask", + expectedGeneratedNameSource: Python, + fs: &subUsmTestData, }, { name: "python - module hello", cmdline: []string{ "python3", "-m", "hello", }, - lang: language.Python, - expectedGeneratedName: "hello", + lang: language.Python, + expectedGeneratedName: "hello", + expectedGeneratedNameSource: CommandLine, }, { name: "ruby - td-agent", cmdline: []string{ "ruby", "/usr/sbin/td-agent", "--log", "/var/log/td-agent/td-agent.log", "--daemon", "/var/run/td-agent/td-agent.pid", }, - lang: language.Ruby, - expectedGeneratedName: "td-agent", + lang: language.Ruby, + expectedGeneratedName: "td-agent", + expectedGeneratedNameSource: CommandLine, }, { name: "java using the -jar flag to define the service", cmdline: []string{ "java", "-Xmx4000m", "-Xms4000m", "-XX:ReservedCodeCacheSize=256m", "-jar", "/opt/sheepdog/bin/myservice.jar", }, - lang: language.Java, - expectedGeneratedName: "myservice", + lang: language.Java, + expectedGeneratedName: "myservice", + expectedGeneratedNameSource: CommandLine, }, { name: "java using the -jar flag to point to a .war", cmdline: []string{ "java", "-Duser.home=/var/jenkins_home", "-Dhudson.lifecycle=hudson.lifecycle.ExitLifecycle", "-jar", "/usr/share/jenkins/jenkins.war", "--httpPort=8000", }, - lang: language.Java, - expectedGeneratedName: "jenkins", + lang: language.Java, + expectedGeneratedName: "jenkins", + expectedGeneratedNameSource: CommandLine, }, { name: "java class name as service", cmdline: []string{ "java", "-Xmx4000m", "-Xms4000m", "-XX:ReservedCodeCacheSize=256m", "com.datadog.example.HelloWorld", }, - lang: language.Java, - expectedGeneratedName: "HelloWorld", + lang: language.Java, + expectedGeneratedName: "HelloWorld", + expectedGeneratedNameSource: CommandLine, }, { name: "java kafka", cmdline: []string{ "java", "-Xmx4000m", "-Xms4000m", "-XX:ReservedCodeCacheSize=256m", "kafka.Kafka", }, - lang: language.Java, - expectedGeneratedName: "Kafka", + lang: language.Java, + expectedGeneratedName: "Kafka", + expectedGeneratedNameSource: CommandLine, }, { name: "java parsing for org.apache projects with cassandra as the service", @@ -194,16 +209,18 @@ func TestExtractServiceMetadata(t *testing.T) { "-cp", "/etc/cassandra:/usr/share/cassandra/lib/HdrHistogram-2.1.9.jar:/usr/share/cassandra/lib/cassandra-driver-core-3.0.1-shaded.jar", "org.apache.cassandra.service.CassandraDaemon", }, - lang: language.Java, - expectedGeneratedName: "cassandra", + lang: language.Java, + expectedGeneratedName: "cassandra", + expectedGeneratedNameSource: CommandLine, }, { name: "java space in java executable path", cmdline: []string{ "/home/dd/my java dir/java", "com.dog.cat", }, - lang: language.Java, - expectedGeneratedName: "cat", + lang: language.Java, + expectedGeneratedName: "cat", + expectedGeneratedNameSource: CommandLine, }, { name: "node js with package.json not present", @@ -215,8 +232,9 @@ func TestExtractServiceMetadata(t *testing.T) { "--", "/somewhere/index.js", }, - lang: language.Node, - expectedGeneratedName: "node", + lang: language.Node, + expectedGeneratedName: "node", + expectedGeneratedNameSource: CommandLine, }, { name: "node js with a broken package.json", @@ -224,9 +242,10 @@ func TestExtractServiceMetadata(t *testing.T) { "/usr/bin/node", "./testdata/inner/app.js", }, - lang: language.Node, - expectedGeneratedName: "app", - fs: &subUsmTestData, + lang: language.Node, + expectedGeneratedName: "app", + expectedGeneratedNameSource: CommandLine, + fs: &subUsmTestData, }, { name: "node js with a broken package.json", @@ -234,9 +253,10 @@ func TestExtractServiceMetadata(t *testing.T) { "/usr/bin/node", "./testdata/inner/link", }, - lang: language.Node, - expectedGeneratedName: "link", - fs: &subUsmTestData, + lang: language.Node, + expectedGeneratedName: "link", + expectedGeneratedNameSource: CommandLine, + fs: &subUsmTestData, }, { name: "node js with a valid package.json", @@ -248,9 +268,10 @@ func TestExtractServiceMetadata(t *testing.T) { "--", "./testdata/index.js", }, - lang: language.Node, - expectedGeneratedName: "my-awesome-package", - fs: &subUsmTestData, + lang: language.Node, + expectedGeneratedName: "my-awesome-package", + fs: &subUsmTestData, + expectedGeneratedNameSource: Nodejs, }, { name: "nodejs .cjs with a valid package.json", @@ -258,9 +279,10 @@ func TestExtractServiceMetadata(t *testing.T) { "/usr/bin/node", "./testdata/foo.cjs", }, - lang: language.Node, - expectedGeneratedName: "my-awesome-package", - fs: &subUsmTestData, + lang: language.Node, + expectedGeneratedName: "my-awesome-package", + expectedGeneratedNameSource: Nodejs, + fs: &subUsmTestData, }, { name: "nodejs .mjs with a valid package.json", @@ -268,9 +290,10 @@ func TestExtractServiceMetadata(t *testing.T) { "/usr/bin/node", "./testdata/bar.mjs", }, - lang: language.Node, - expectedGeneratedName: "my-awesome-package", - fs: &subUsmTestData, + lang: language.Node, + expectedGeneratedName: "my-awesome-package", + expectedGeneratedNameSource: Nodejs, + fs: &subUsmTestData, }, { name: "node js with a symlink to a .js file and valid package.json", @@ -282,10 +305,11 @@ func TestExtractServiceMetadata(t *testing.T) { "./testdata/bins/broken", "./testdata/bins/json-server", }, - lang: language.Node, - expectedGeneratedName: "json-server-package", - skipOnWindows: true, - fs: &subUsmTestData, + lang: language.Node, + expectedGeneratedName: "json-server-package", + expectedGeneratedNameSource: Nodejs, + skipOnWindows: true, + fs: &subUsmTestData, }, { name: "node js with a valid nested package.json and cwd", @@ -297,10 +321,11 @@ func TestExtractServiceMetadata(t *testing.T) { "--", "index.js", }, - lang: language.Node, - envs: map[string]string{"PWD": "testdata/deep"}, // it's relative but it's ok for testing purposes - fs: &subUsmTestData, - expectedGeneratedName: "my-awesome-package", + lang: language.Node, + envs: map[string]string{"PWD": "testdata/deep"}, // it's relative but it's ok for testing purposes + fs: &subUsmTestData, + expectedGeneratedName: "my-awesome-package", + expectedGeneratedNameSource: Nodejs, }, { name: "spring boot default options", @@ -309,8 +334,9 @@ func TestExtractServiceMetadata(t *testing.T) { "-jar", springBootAppFullPath, }, - lang: language.Java, - expectedGeneratedName: "default-app", + lang: language.Java, + expectedGeneratedName: "default-app", + expectedGeneratedNameSource: Spring, }, { name: "wildfly 18 standalone", @@ -338,11 +364,12 @@ func TestExtractServiceMetadata(t *testing.T) { "-Djboss.home.dir=" + jbossTestAppRoot, "-Djboss.server.base.dir=" + jbossTestAppRoot + "/standalone", }, - lang: language.Java, - expectedGeneratedName: "jboss-modules", - expectedAdditionalServices: []string{"my-jboss-webapp", "some_context_root", "web3"}, - fs: &sub, - envs: map[string]string{"PWD": "/sibiling"}, + lang: language.Java, + expectedGeneratedName: "jboss-modules", + expectedAdditionalServices: []string{"my-jboss-webapp", "some_context_root", "web3"}, + fs: &sub, + envs: map[string]string{"PWD": "/sibiling"}, + expectedGeneratedNameSource: JBoss, }, { name: "wildfly 18 domain", @@ -373,11 +400,12 @@ func TestExtractServiceMetadata(t *testing.T) { "" + jbossTestAppRoot + "/modules", "org.jboss.as.server", }, - lang: language.Java, - expectedGeneratedName: "jboss-modules", - expectedAdditionalServices: []string{"web3", "web4"}, - fs: &sub, - envs: map[string]string{"PWD": "/sibiling"}, + lang: language.Java, + expectedGeneratedName: "jboss-modules", + expectedGeneratedNameSource: JBoss, + expectedAdditionalServices: []string{"web3", "web4"}, + fs: &sub, + envs: map[string]string{"PWD": "/sibiling"}, }, { name: "weblogic 12", @@ -397,19 +425,21 @@ func TestExtractServiceMetadata(t *testing.T) { "-Dweblogic.home=/u01/oracle/wlserver/server", "weblogic.Server", }, - lang: language.Java, - envs: map[string]string{"PWD": weblogicTestAppRootAbsolute}, - expectedGeneratedName: "Server", - expectedAdditionalServices: []string{"my_context", "sample4", "some_context_root"}, + lang: language.Java, + envs: map[string]string{"PWD": weblogicTestAppRootAbsolute}, + expectedGeneratedName: "Server", + expectedGeneratedNameSource: WebLogic, + expectedAdditionalServices: []string{"my_context", "sample4", "some_context_root"}, }, { name: "java with dd_service as system property", cmdline: []string{ "/usr/bin/java", "-Ddd.service=custom", "-jar", "app.jar", }, - lang: language.Java, - expectedDDService: "custom", - expectedGeneratedName: "app", + lang: language.Java, + expectedDDService: "custom", + expectedGeneratedName: "app", + expectedGeneratedNameSource: CommandLine, }, { // The system property takes priority over the environment variable, see @@ -418,10 +448,11 @@ func TestExtractServiceMetadata(t *testing.T) { cmdline: []string{ "/usr/bin/java", "-Ddd.service=dd-service-from-property", "-jar", "app.jar", }, - lang: language.Java, - envs: map[string]string{"DD_SERVICE": "dd-service-from-env"}, - expectedDDService: "dd-service-from-property", - expectedGeneratedName: "app", + lang: language.Java, + envs: map[string]string{"DD_SERVICE": "dd-service-from-env"}, + expectedDDService: "dd-service-from-property", + expectedGeneratedName: "app", + expectedGeneratedNameSource: CommandLine, }, { name: "Tomcat 10.X", @@ -445,34 +476,38 @@ func TestExtractServiceMetadata(t *testing.T) { "org.apache.catalina.startup.Bootstrap", "start", }, - lang: language.Java, - expectedGeneratedName: "catalina", - expectedAdditionalServices: []string{"app2", "custom"}, - fs: &subUsmTestData, + lang: language.Java, + expectedGeneratedName: "catalina", + expectedGeneratedNameSource: Tomcat, + expectedAdditionalServices: []string{"app2", "custom"}, + fs: &subUsmTestData, }, { name: "dotnet cmd with dll", cmdline: []string{ "/usr/bin/dotnet", "./myservice.dll", }, - lang: language.DotNet, - expectedGeneratedName: "myservice", + lang: language.DotNet, + expectedGeneratedName: "myservice", + expectedGeneratedNameSource: CommandLine, }, { name: "dotnet cmd with dll and options", cmdline: []string{ "/usr/bin/dotnet", "-v", "--", "/app/lib/myservice.dll", }, - lang: language.DotNet, - expectedGeneratedName: "myservice", + lang: language.DotNet, + expectedGeneratedName: "myservice", + expectedGeneratedNameSource: CommandLine, }, { name: "dotnet cmd with unrecognized options", cmdline: []string{ "/usr/bin/dotnet", "run", "--project", "./projects/proj1/proj1.csproj", }, - lang: language.DotNet, - expectedGeneratedName: "dotnet", + lang: language.DotNet, + expectedGeneratedName: "dotnet", + expectedGeneratedNameSource: CommandLine, }, { name: "PHP Laravel", @@ -481,8 +516,9 @@ func TestExtractServiceMetadata(t *testing.T) { "artisan", "serve", }, - lang: language.PHP, - expectedGeneratedName: "laravel", + lang: language.PHP, + expectedGeneratedName: "laravel", + expectedGeneratedNameSource: Laravel, }, { name: "Plain PHP with INI", @@ -491,9 +527,10 @@ func TestExtractServiceMetadata(t *testing.T) { "-ddatadog.service=foo", "swoole-server.php", }, - lang: language.PHP, - expectedDDService: "foo", - expectedGeneratedName: "php", + lang: language.PHP, + expectedDDService: "foo", + expectedGeneratedName: "php", + expectedGeneratedNameSource: CommandLine, }, { name: "PHP with version number", @@ -502,8 +539,9 @@ func TestExtractServiceMetadata(t *testing.T) { "artisan", "migrate:fresh", }, - lang: language.PHP, - expectedGeneratedName: "laravel", + lang: language.PHP, + expectedGeneratedName: "laravel", + expectedGeneratedNameSource: Laravel, }, { name: "PHP with two-digit version number", @@ -512,8 +550,9 @@ func TestExtractServiceMetadata(t *testing.T) { "artisan", "migrate:fresh", }, - lang: language.PHP, - expectedGeneratedName: "laravel", + lang: language.PHP, + expectedGeneratedName: "laravel", + expectedGeneratedNameSource: Laravel, }, { name: "PHP-FPM shouldn't trigger php parsing", @@ -521,7 +560,8 @@ func TestExtractServiceMetadata(t *testing.T) { "php-fpm", "artisan", }, - expectedGeneratedName: "php-fpm", + expectedGeneratedName: "php-fpm", + expectedGeneratedNameSource: CommandLine, }, { name: "PHP-FPM with version number shouldn't trigger php parsing", @@ -529,32 +569,36 @@ func TestExtractServiceMetadata(t *testing.T) { "php8.1-fpm", "artisan", }, - expectedGeneratedName: "php8", + expectedGeneratedName: "php8", + expectedGeneratedNameSource: CommandLine, }, { - name: "DD_SERVICE_set_manually", - cmdline: []string{"java", "-jar", "Foo.jar"}, - lang: language.Java, - envs: map[string]string{"DD_SERVICE": "howdy"}, - expectedDDService: "howdy", - expectedGeneratedName: "Foo", + name: "DD_SERVICE_set_manually", + cmdline: []string{"java", "-jar", "Foo.jar"}, + lang: language.Java, + envs: map[string]string{"DD_SERVICE": "howdy"}, + expectedDDService: "howdy", + expectedGeneratedName: "Foo", + expectedGeneratedNameSource: CommandLine, }, { - name: "DD_SERVICE_set_manually_tags", - cmdline: []string{"java", "-jar", "Foo.jar"}, - lang: language.Java, - envs: map[string]string{"DD_TAGS": "service:howdy"}, - expectedDDService: "howdy", - expectedGeneratedName: "Foo", + name: "DD_SERVICE_set_manually_tags", + cmdline: []string{"java", "-jar", "Foo.jar"}, + lang: language.Java, + envs: map[string]string{"DD_TAGS": "service:howdy"}, + expectedDDService: "howdy", + expectedGeneratedName: "Foo", + expectedGeneratedNameSource: CommandLine, }, { - name: "DD_SERVICE_set_manually_injection", - cmdline: []string{"java", "-jar", "Foo.jar"}, - lang: language.Java, - envs: map[string]string{"DD_SERVICE": "howdy", "DD_INJECTION_ENABLED": "tracer,service_name"}, - expectedDDService: "howdy", - expectedGeneratedName: "Foo", - ddServiceInjected: true, + name: "DD_SERVICE_set_manually_injection", + cmdline: []string{"java", "-jar", "Foo.jar"}, + lang: language.Java, + envs: map[string]string{"DD_SERVICE": "howdy", "DD_INJECTION_ENABLED": "tracer,service_name"}, + expectedDDService: "howdy", + expectedGeneratedName: "Foo", + expectedGeneratedNameSource: CommandLine, + ddServiceInjected: true, }, { name: "gunicorn simple", @@ -563,8 +607,9 @@ func TestExtractServiceMetadata(t *testing.T) { "--workers=2", "test:app", }, - lang: language.Python, - expectedGeneratedName: "test", + lang: language.Python, + expectedGeneratedName: "test", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn simple with python", @@ -574,8 +619,9 @@ func TestExtractServiceMetadata(t *testing.T) { "--workers=2", "foo:create_app()", }, - lang: language.Python, - expectedGeneratedName: "foo", + lang: language.Python, + expectedGeneratedName: "foo", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn from name", @@ -588,7 +634,8 @@ func TestExtractServiceMetadata(t *testing.T) { "dummy", "test:app", }, - expectedGeneratedName: "dummy", + expectedGeneratedName: "dummy", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn from name (long arg)", @@ -600,7 +647,8 @@ func TestExtractServiceMetadata(t *testing.T) { "--name=dummy", "test:app", }, - expectedGeneratedName: "dummy", + expectedGeneratedName: "dummy", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn from name in env", @@ -608,16 +656,18 @@ func TestExtractServiceMetadata(t *testing.T) { "gunicorn", "test:app", }, - envs: map[string]string{"GUNICORN_CMD_ARGS": "--bind=127.0.0.1:8080 --workers=3 -n dummy"}, - expectedGeneratedName: "dummy", + envs: map[string]string{"GUNICORN_CMD_ARGS": "--bind=127.0.0.1:8080 --workers=3 -n dummy"}, + expectedGeneratedName: "dummy", + expectedGeneratedNameSource: Gunicorn, }, { name: "gunicorn without app found", cmdline: []string{ "gunicorn", }, - envs: map[string]string{"GUNICORN_CMD_ARGS": "--bind=127.0.0.1:8080 --workers=3"}, - expectedGeneratedName: "gunicorn", + envs: map[string]string{"GUNICORN_CMD_ARGS": "--bind=127.0.0.1:8080 --workers=3"}, + expectedGeneratedName: "gunicorn", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn with partial wsgi app", @@ -625,7 +675,8 @@ func TestExtractServiceMetadata(t *testing.T) { "gunicorn", "my.package", }, - expectedGeneratedName: "my.package", + expectedGeneratedName: "my.package", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn with empty WSGI_APP env", @@ -633,16 +684,18 @@ func TestExtractServiceMetadata(t *testing.T) { "gunicorn", "my.package", }, - envs: map[string]string{"WSGI_APP": ""}, - expectedGeneratedName: "my.package", + envs: map[string]string{"WSGI_APP": ""}, + expectedGeneratedName: "my.package", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn with WSGI_APP env", cmdline: []string{ "gunicorn", }, - envs: map[string]string{"WSGI_APP": "test:app"}, - expectedGeneratedName: "test", + envs: map[string]string{"WSGI_APP": "test:app"}, + expectedGeneratedName: "test", + expectedGeneratedNameSource: Gunicorn, }, { name: "gunicorn with replaced cmdline with colon", @@ -651,7 +704,8 @@ func TestExtractServiceMetadata(t *testing.T) { "master", "[domains.foo.apps.bar:create_server()]", }, - expectedGeneratedName: "domains.foo.apps.bar", + expectedGeneratedName: "domains.foo.apps.bar", + expectedGeneratedNameSource: CommandLine, }, { name: "gunicorn with replaced cmdline", @@ -660,7 +714,8 @@ func TestExtractServiceMetadata(t *testing.T) { "master", "[mcservice]", }, - expectedGeneratedName: "mcservice", + expectedGeneratedName: "mcservice", + expectedGeneratedNameSource: CommandLine, }, } @@ -686,6 +741,7 @@ func TestExtractServiceMetadata(t *testing.T) { require.Equal(t, tt.expectedGeneratedName, meta.Name) require.Equal(t, tt.expectedAdditionalServices, meta.AdditionalNames) require.Equal(t, tt.ddServiceInjected, meta.DDServiceInjected) + require.Equal(t, tt.expectedGeneratedNameSource, meta.Source) } }) }