diff --git a/.chloggen/sqlserver-session-attributes.yaml b/.chloggen/sqlserver-session-attributes.yaml new file mode 100644 index 0000000000000..543a657e4b258 --- /dev/null +++ b/.chloggen/sqlserver-session-attributes.yaml @@ -0,0 +1,31 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog) +component: receiver/sqlserver + +# A brief description of the change. Surround your text with quotes (") if it needs to start with a backtick (`). +note: Add session attributes to `db.server.query_sample` event. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [48346] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + The `db.server.query_sample` log records now include: + + - `sqlserver.client.app.name`: Name of the client application that initiated the session. + - `sqlserver.session.started`: ISO 8601 timestamp of when the session was established. + - `sqlserver.session.duration`: Total elapsed time in seconds the session has been actively executing requests. +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/receiver/sqlserverreceiver/documentation.md b/receiver/sqlserverreceiver/documentation.md index e8e35eefe69b9..d1d7c2dc06d6d 100644 --- a/receiver/sqlserverreceiver/documentation.md +++ b/receiver/sqlserverreceiver/documentation.md @@ -582,6 +582,7 @@ query sample | network.peer.port | TCP port used by the peer client. | Any Int | - | | sqlserver.blocking_session_id | Session ID that is blocking the current session. 0 if none. | Any Int | - | | sqlserver.blocking.start_time | Timestamp of when the current blocking wait began (ISO 8601 format). | Any Str | - | +| sqlserver.client.app.name | Name of the client application that initiated the session. | Any Str | - | | sqlserver.context_info | Context information for the session, represented as a hexadecimal string. | Any Str | - | | sqlserver.command | SQL command type being executed. | Any Str | - | | sqlserver.cpu_time | CPU time consumed by the query, in seconds. | Any Double | - | @@ -599,6 +600,8 @@ query sample | sqlserver.wait.resource.id | SQL Server identifier for the locked or waited-on resource, if available. | Any Str | - | | sqlserver.wait.resource.type | SQL Server type of the locked or waited-on resource, if available. | Any Str | - | | sqlserver.row_count | Number of rows affected or returned by the query. | Any Int | - | +| sqlserver.session.duration | Total elapsed time in seconds the session has been actively executing requests. | Any Double | - | +| sqlserver.session.started | Timestamp when the session was established (ISO 8601 format). | Any Str | - | | sqlserver.session_id | ID of the SQL Server session. | Any Int | - | | sqlserver.session_status | Status of the session (e.g., running, sleeping). | Any Str | - | | sqlserver.total_elapsed_time | Total elapsed time for completed executions of this plan, reported in delta seconds. | Any Double | - | diff --git a/receiver/sqlserverreceiver/internal/metadata/generated_logs.go b/receiver/sqlserverreceiver/internal/metadata/generated_logs.go index 4f8bf76172c01..80dc34e515cdd 100644 --- a/receiver/sqlserverreceiver/internal/metadata/generated_logs.go +++ b/receiver/sqlserverreceiver/internal/metadata/generated_logs.go @@ -18,7 +18,7 @@ type eventDbServerQuerySample struct { config EventConfig // event config provided by user. } -func (e *eventDbServerQuerySample) recordEvent(ctx context.Context, timestamp pcommon.Timestamp, clientAddressAttributeValue string, clientPortAttributeValue int64, dbNamespaceAttributeValue string, dbQueryTextAttributeValue string, dbSystemNameAttributeValue string, networkPeerAddressAttributeValue string, networkPeerPortAttributeValue int64, sqlserverBlockingSessionIDAttributeValue int64, sqlserverBlockingStartTimeAttributeValue string, sqlserverContextInfoAttributeValue string, sqlserverCommandAttributeValue string, sqlserverCPUTimeAttributeValue float64, sqlserverDeadlockPriorityAttributeValue int64, sqlserverEstimatedCompletionTimeAttributeValue float64, sqlserverLockTimeoutAttributeValue float64, sqlserverLogicalReadsAttributeValue int64, sqlserverOpenTransactionCountAttributeValue int64, sqlserverPercentCompleteAttributeValue float64, sqlserverQueryHashAttributeValue string, sqlserverQueryPlanHashAttributeValue string, sqlserverQueryStartAttributeValue string, sqlserverReadsAttributeValue int64, sqlserverRequestStatusAttributeValue string, sqlserverWaitResourceIDAttributeValue string, sqlserverWaitResourceTypeAttributeValue string, sqlserverRowCountAttributeValue int64, sqlserverSessionIDAttributeValue int64, sqlserverSessionStatusAttributeValue string, sqlserverTotalElapsedTimeAttributeValue float64, sqlserverTransactionIDAttributeValue int64, sqlserverTransactionIsolationLevelAttributeValue int64, sqlserverWaitResourceAttributeValue string, sqlserverWaitTimeAttributeValue float64, sqlserverWaitTypeAttributeValue string, sqlserverWritesAttributeValue int64, userNameAttributeValue string, sqlserverProcedureIDAttributeValue string, sqlserverProcedureNameAttributeValue string) { +func (e *eventDbServerQuerySample) recordEvent(ctx context.Context, timestamp pcommon.Timestamp, clientAddressAttributeValue string, clientPortAttributeValue int64, dbNamespaceAttributeValue string, dbQueryTextAttributeValue string, dbSystemNameAttributeValue string, networkPeerAddressAttributeValue string, networkPeerPortAttributeValue int64, sqlserverBlockingSessionIDAttributeValue int64, sqlserverBlockingStartTimeAttributeValue string, sqlserverClientAppNameAttributeValue string, sqlserverContextInfoAttributeValue string, sqlserverCommandAttributeValue string, sqlserverCPUTimeAttributeValue float64, sqlserverDeadlockPriorityAttributeValue int64, sqlserverEstimatedCompletionTimeAttributeValue float64, sqlserverLockTimeoutAttributeValue float64, sqlserverLogicalReadsAttributeValue int64, sqlserverOpenTransactionCountAttributeValue int64, sqlserverPercentCompleteAttributeValue float64, sqlserverQueryHashAttributeValue string, sqlserverQueryPlanHashAttributeValue string, sqlserverQueryStartAttributeValue string, sqlserverReadsAttributeValue int64, sqlserverRequestStatusAttributeValue string, sqlserverWaitResourceIDAttributeValue string, sqlserverWaitResourceTypeAttributeValue string, sqlserverRowCountAttributeValue int64, sqlserverSessionDurationAttributeValue float64, sqlserverSessionStartedAttributeValue string, sqlserverSessionIDAttributeValue int64, sqlserverSessionStatusAttributeValue string, sqlserverTotalElapsedTimeAttributeValue float64, sqlserverTransactionIDAttributeValue int64, sqlserverTransactionIsolationLevelAttributeValue int64, sqlserverWaitResourceAttributeValue string, sqlserverWaitTimeAttributeValue float64, sqlserverWaitTypeAttributeValue string, sqlserverWritesAttributeValue int64, userNameAttributeValue string, sqlserverProcedureIDAttributeValue string, sqlserverProcedureNameAttributeValue string) { if !e.config.Enabled { return } @@ -39,6 +39,7 @@ func (e *eventDbServerQuerySample) recordEvent(ctx context.Context, timestamp pc dp.Attributes().PutInt("network.peer.port", networkPeerPortAttributeValue) dp.Attributes().PutInt("sqlserver.blocking_session_id", sqlserverBlockingSessionIDAttributeValue) dp.Attributes().PutStr("sqlserver.blocking.start_time", sqlserverBlockingStartTimeAttributeValue) + dp.Attributes().PutStr("sqlserver.client.app.name", sqlserverClientAppNameAttributeValue) dp.Attributes().PutStr("sqlserver.context_info", sqlserverContextInfoAttributeValue) dp.Attributes().PutStr("sqlserver.command", sqlserverCommandAttributeValue) dp.Attributes().PutDouble("sqlserver.cpu_time", sqlserverCPUTimeAttributeValue) @@ -56,6 +57,8 @@ func (e *eventDbServerQuerySample) recordEvent(ctx context.Context, timestamp pc dp.Attributes().PutStr("sqlserver.wait.resource.id", sqlserverWaitResourceIDAttributeValue) dp.Attributes().PutStr("sqlserver.wait.resource.type", sqlserverWaitResourceTypeAttributeValue) dp.Attributes().PutInt("sqlserver.row_count", sqlserverRowCountAttributeValue) + dp.Attributes().PutDouble("sqlserver.session.duration", sqlserverSessionDurationAttributeValue) + dp.Attributes().PutStr("sqlserver.session.started", sqlserverSessionStartedAttributeValue) dp.Attributes().PutInt("sqlserver.session_id", sqlserverSessionIDAttributeValue) dp.Attributes().PutStr("sqlserver.session_status", sqlserverSessionStatusAttributeValue) dp.Attributes().PutDouble("sqlserver.total_elapsed_time", sqlserverTotalElapsedTimeAttributeValue) @@ -292,8 +295,8 @@ func (lb *LogsBuilder) Emit(options ...ResourceLogsOption) plog.Logs { } // RecordDbServerQuerySampleEvent adds a log record of db.server.query_sample event. -func (lb *LogsBuilder) RecordDbServerQuerySampleEvent(ctx context.Context, timestamp pcommon.Timestamp, clientAddressAttributeValue string, clientPortAttributeValue int64, dbNamespaceAttributeValue string, dbQueryTextAttributeValue string, dbSystemNameAttributeValue string, networkPeerAddressAttributeValue string, networkPeerPortAttributeValue int64, sqlserverBlockingSessionIDAttributeValue int64, sqlserverBlockingStartTimeAttributeValue string, sqlserverContextInfoAttributeValue string, sqlserverCommandAttributeValue string, sqlserverCPUTimeAttributeValue float64, sqlserverDeadlockPriorityAttributeValue int64, sqlserverEstimatedCompletionTimeAttributeValue float64, sqlserverLockTimeoutAttributeValue float64, sqlserverLogicalReadsAttributeValue int64, sqlserverOpenTransactionCountAttributeValue int64, sqlserverPercentCompleteAttributeValue float64, sqlserverQueryHashAttributeValue string, sqlserverQueryPlanHashAttributeValue string, sqlserverQueryStartAttributeValue string, sqlserverReadsAttributeValue int64, sqlserverRequestStatusAttributeValue string, sqlserverWaitResourceIDAttributeValue string, sqlserverWaitResourceTypeAttributeValue string, sqlserverRowCountAttributeValue int64, sqlserverSessionIDAttributeValue int64, sqlserverSessionStatusAttributeValue string, sqlserverTotalElapsedTimeAttributeValue float64, sqlserverTransactionIDAttributeValue int64, sqlserverTransactionIsolationLevelAttributeValue int64, sqlserverWaitResourceAttributeValue string, sqlserverWaitTimeAttributeValue float64, sqlserverWaitTypeAttributeValue string, sqlserverWritesAttributeValue int64, userNameAttributeValue string, sqlserverProcedureIDAttributeValue string, sqlserverProcedureNameAttributeValue string) { - lb.eventDbServerQuerySample.recordEvent(ctx, timestamp, clientAddressAttributeValue, clientPortAttributeValue, dbNamespaceAttributeValue, dbQueryTextAttributeValue, dbSystemNameAttributeValue, networkPeerAddressAttributeValue, networkPeerPortAttributeValue, sqlserverBlockingSessionIDAttributeValue, sqlserverBlockingStartTimeAttributeValue, sqlserverContextInfoAttributeValue, sqlserverCommandAttributeValue, sqlserverCPUTimeAttributeValue, sqlserverDeadlockPriorityAttributeValue, sqlserverEstimatedCompletionTimeAttributeValue, sqlserverLockTimeoutAttributeValue, sqlserverLogicalReadsAttributeValue, sqlserverOpenTransactionCountAttributeValue, sqlserverPercentCompleteAttributeValue, sqlserverQueryHashAttributeValue, sqlserverQueryPlanHashAttributeValue, sqlserverQueryStartAttributeValue, sqlserverReadsAttributeValue, sqlserverRequestStatusAttributeValue, sqlserverWaitResourceIDAttributeValue, sqlserverWaitResourceTypeAttributeValue, sqlserverRowCountAttributeValue, sqlserverSessionIDAttributeValue, sqlserverSessionStatusAttributeValue, sqlserverTotalElapsedTimeAttributeValue, sqlserverTransactionIDAttributeValue, sqlserverTransactionIsolationLevelAttributeValue, sqlserverWaitResourceAttributeValue, sqlserverWaitTimeAttributeValue, sqlserverWaitTypeAttributeValue, sqlserverWritesAttributeValue, userNameAttributeValue, sqlserverProcedureIDAttributeValue, sqlserverProcedureNameAttributeValue) +func (lb *LogsBuilder) RecordDbServerQuerySampleEvent(ctx context.Context, timestamp pcommon.Timestamp, clientAddressAttributeValue string, clientPortAttributeValue int64, dbNamespaceAttributeValue string, dbQueryTextAttributeValue string, dbSystemNameAttributeValue string, networkPeerAddressAttributeValue string, networkPeerPortAttributeValue int64, sqlserverBlockingSessionIDAttributeValue int64, sqlserverBlockingStartTimeAttributeValue string, sqlserverClientAppNameAttributeValue string, sqlserverContextInfoAttributeValue string, sqlserverCommandAttributeValue string, sqlserverCPUTimeAttributeValue float64, sqlserverDeadlockPriorityAttributeValue int64, sqlserverEstimatedCompletionTimeAttributeValue float64, sqlserverLockTimeoutAttributeValue float64, sqlserverLogicalReadsAttributeValue int64, sqlserverOpenTransactionCountAttributeValue int64, sqlserverPercentCompleteAttributeValue float64, sqlserverQueryHashAttributeValue string, sqlserverQueryPlanHashAttributeValue string, sqlserverQueryStartAttributeValue string, sqlserverReadsAttributeValue int64, sqlserverRequestStatusAttributeValue string, sqlserverWaitResourceIDAttributeValue string, sqlserverWaitResourceTypeAttributeValue string, sqlserverRowCountAttributeValue int64, sqlserverSessionDurationAttributeValue float64, sqlserverSessionStartedAttributeValue string, sqlserverSessionIDAttributeValue int64, sqlserverSessionStatusAttributeValue string, sqlserverTotalElapsedTimeAttributeValue float64, sqlserverTransactionIDAttributeValue int64, sqlserverTransactionIsolationLevelAttributeValue int64, sqlserverWaitResourceAttributeValue string, sqlserverWaitTimeAttributeValue float64, sqlserverWaitTypeAttributeValue string, sqlserverWritesAttributeValue int64, userNameAttributeValue string, sqlserverProcedureIDAttributeValue string, sqlserverProcedureNameAttributeValue string) { + lb.eventDbServerQuerySample.recordEvent(ctx, timestamp, clientAddressAttributeValue, clientPortAttributeValue, dbNamespaceAttributeValue, dbQueryTextAttributeValue, dbSystemNameAttributeValue, networkPeerAddressAttributeValue, networkPeerPortAttributeValue, sqlserverBlockingSessionIDAttributeValue, sqlserverBlockingStartTimeAttributeValue, sqlserverClientAppNameAttributeValue, sqlserverContextInfoAttributeValue, sqlserverCommandAttributeValue, sqlserverCPUTimeAttributeValue, sqlserverDeadlockPriorityAttributeValue, sqlserverEstimatedCompletionTimeAttributeValue, sqlserverLockTimeoutAttributeValue, sqlserverLogicalReadsAttributeValue, sqlserverOpenTransactionCountAttributeValue, sqlserverPercentCompleteAttributeValue, sqlserverQueryHashAttributeValue, sqlserverQueryPlanHashAttributeValue, sqlserverQueryStartAttributeValue, sqlserverReadsAttributeValue, sqlserverRequestStatusAttributeValue, sqlserverWaitResourceIDAttributeValue, sqlserverWaitResourceTypeAttributeValue, sqlserverRowCountAttributeValue, sqlserverSessionDurationAttributeValue, sqlserverSessionStartedAttributeValue, sqlserverSessionIDAttributeValue, sqlserverSessionStatusAttributeValue, sqlserverTotalElapsedTimeAttributeValue, sqlserverTransactionIDAttributeValue, sqlserverTransactionIsolationLevelAttributeValue, sqlserverWaitResourceAttributeValue, sqlserverWaitTimeAttributeValue, sqlserverWaitTypeAttributeValue, sqlserverWritesAttributeValue, userNameAttributeValue, sqlserverProcedureIDAttributeValue, sqlserverProcedureNameAttributeValue) } // RecordDbServerTopQueryEvent adds a log record of db.server.top_query event. diff --git a/receiver/sqlserverreceiver/internal/metadata/generated_logs_test.go b/receiver/sqlserverreceiver/internal/metadata/generated_logs_test.go index aa26b37f08144..c3b09728f16b4 100644 --- a/receiver/sqlserverreceiver/internal/metadata/generated_logs_test.go +++ b/receiver/sqlserverreceiver/internal/metadata/generated_logs_test.go @@ -135,7 +135,7 @@ func TestLogsBuilder(t *testing.T) { allEventsCount := 0 allEventsCount++ - lb.RecordDbServerQuerySampleEvent(ctx, timestamp, "client.address-val", 11, "db.namespace-val", "db.query.text-val", "db.system.name-val", "network.peer.address-val", 17, 29, "sqlserver.blocking.start_time-val", "sqlserver.context_info-val", "sqlserver.command-val", 18.100000, 27, 35.100000, 22.100000, 23, 32, 26.100000, "sqlserver.query_hash-val", "sqlserver.query_plan_hash-val", "sqlserver.query_start-val", 15, "sqlserver.request_status-val", "sqlserver.wait.resource.id-val", "sqlserver.wait.resource.type-val", 19, 20, "sqlserver.session_status-val", 28.100000, 24, 37, "sqlserver.wait_resource-val", 19.100000, "sqlserver.wait_type-val", 16, "user.name-val", "sqlserver.procedure_id-val", "sqlserver.procedure_name-val") + lb.RecordDbServerQuerySampleEvent(ctx, timestamp, "client.address-val", 11, "db.namespace-val", "db.query.text-val", "db.system.name-val", "network.peer.address-val", 17, 29, "sqlserver.blocking.start_time-val", "sqlserver.client.app.name-val", "sqlserver.context_info-val", "sqlserver.command-val", 18.100000, 27, 35.100000, 22.100000, 23, 32, 26.100000, "sqlserver.query_hash-val", "sqlserver.query_plan_hash-val", "sqlserver.query_start-val", 15, "sqlserver.request_status-val", "sqlserver.wait.resource.id-val", "sqlserver.wait.resource.type-val", 19, 26.100000, "sqlserver.session.started-val", 20, "sqlserver.session_status-val", 28.100000, 24, 37, "sqlserver.wait_resource-val", 19.100000, "sqlserver.wait_type-val", 16, "user.name-val", "sqlserver.procedure_id-val", "sqlserver.procedure_name-val") allEventsCount++ lb.RecordDbServerTopQueryEvent(ctx, timestamp, 27.100000, "db.query.text-val", 25, 29, 30, 30, "sqlserver.query_hash-val", "sqlserver.query_plan-val", "sqlserver.query_plan_hash-val", 20, 28.100000, 24, "server.address-val", 11, "db.system.name-val", 35, "sqlserver.procedure_id-val", "sqlserver.procedure_name-val") @@ -204,6 +204,9 @@ func TestLogsBuilder(t *testing.T) { attrVal, ok = lr.Attributes().Get("sqlserver.blocking.start_time") assert.True(t, ok) assert.Equal(t, "sqlserver.blocking.start_time-val", attrVal.Str()) + attrVal, ok = lr.Attributes().Get("sqlserver.client.app.name") + assert.True(t, ok) + assert.Equal(t, "sqlserver.client.app.name-val", attrVal.Str()) attrVal, ok = lr.Attributes().Get("sqlserver.context_info") assert.True(t, ok) assert.Equal(t, "sqlserver.context_info-val", attrVal.Str()) @@ -255,6 +258,12 @@ func TestLogsBuilder(t *testing.T) { attrVal, ok = lr.Attributes().Get("sqlserver.row_count") assert.True(t, ok) assert.EqualValues(t, 19, attrVal.Int()) + attrVal, ok = lr.Attributes().Get("sqlserver.session.duration") + assert.True(t, ok) + assert.Equal(t, 26.100000, attrVal.Double()) + attrVal, ok = lr.Attributes().Get("sqlserver.session.started") + assert.True(t, ok) + assert.Equal(t, "sqlserver.session.started-val", attrVal.Str()) attrVal, ok = lr.Attributes().Get("sqlserver.session_id") assert.True(t, ok) assert.EqualValues(t, 20, attrVal.Int()) diff --git a/receiver/sqlserverreceiver/metadata.yaml b/receiver/sqlserverreceiver/metadata.yaml index 189500a56cf66..f272d665a2d51 100644 --- a/receiver/sqlserverreceiver/metadata.yaml +++ b/receiver/sqlserverreceiver/metadata.yaml @@ -133,6 +133,10 @@ attributes: description: Session ID that is blocking the current session. 0 if none. type: int requirement_level: recommended + sqlserver.client.app.name: + description: Name of the client application that initiated the session. + type: string + requirement_level: recommended sqlserver.command: description: SQL command type being executed. type: string @@ -214,6 +218,14 @@ attributes: description: Number of rows affected or returned by the query. type: int requirement_level: recommended + sqlserver.session.duration: + description: Total elapsed time in seconds the session has been actively executing requests. + type: double + requirement_level: recommended + sqlserver.session.started: + description: Timestamp when the session was established (ISO 8601 format). + type: string + requirement_level: recommended sqlserver.session_id: description: ID of the SQL Server session. type: int @@ -327,6 +339,7 @@ events: - network.peer.port - sqlserver.blocking_session_id - sqlserver.blocking.start_time + - sqlserver.client.app.name - sqlserver.context_info - sqlserver.command - sqlserver.cpu_time @@ -344,6 +357,9 @@ events: - sqlserver.wait.resource.id - sqlserver.wait.resource.type - sqlserver.row_count + - sqlserver.session.duration + + - sqlserver.session.started - sqlserver.session_id - sqlserver.session_status - sqlserver.total_elapsed_time diff --git a/receiver/sqlserverreceiver/scraper.go b/receiver/sqlserverreceiver/scraper.go index f451da3d37772..14d20fb1ca928 100644 --- a/receiver/sqlserverreceiver/scraper.go +++ b/receiver/sqlserverreceiver/scraper.go @@ -1074,6 +1074,7 @@ func (s *sqlServerScraperHelper) recordDatabaseSampleQuery(ctx context.Context) const blockingSessionID = "blocking_session_id" const blockingStartTime = "blocking_start_time" const clientAddress = "client_address" + const clientAppName = "client_app_name" const clientPort = "client_port" const command = "command" const contextInfo = "context_info" @@ -1092,7 +1093,9 @@ func (s *sqlServerScraperHelper) recordDatabaseSampleQuery(ctx context.Context) const reads = "reads" const requestStatus = "request_status" const rowCount = "row_count" + const sessionDurationMillisecond = "session_duration" const sessionID = "session_id" + const sessionStarted = "session_started" const sessionStatus = "session_status" const statementText = "statement_text" const totalElapsedTimeMillisecond = "total_elapsed_time" @@ -1219,6 +1222,9 @@ func (s *sqlServerScraperHelper) recordDatabaseSampleQuery(ctx context.Context) rowCountVal := s.retrieveValue(row, rowCount, &errs, retrieveInt).(int64) sessionIDVal := s.retrieveValue(row, sessionID, &errs, retrieveInt).(int64) sessionStatusVal := row[sessionStatus] + sessionDurationSecondVal := s.retrieveValue(row, sessionDurationMillisecond, &errs, retrieveIntAndConvert(func(i int64) any { + return float64(i) / 1000.0 + })).(float64) totalElapsedTimeSecondVal := s.retrieveValue(row, totalElapsedTimeMillisecond, &errs, retrieveIntAndConvert(func(i int64) any { return float64(i) / 1000.0 })).(float64) @@ -1230,6 +1236,8 @@ func (s *sqlServerScraperHelper) recordDatabaseSampleQuery(ctx context.Context) waitTimeSecondVal := float64(waitTimeMillisecondVal) / 1000.0 resourceTypeVal, resourceIDVal := parseWaitResource(waitResourceVal) blockingStartTimeVal := row[blockingStartTime] + clientAppNameVal := row[clientAppName] + sessionStartedVal := row[sessionStarted] waitTypeVal := row[waitType] writesVal := s.retrieveValue(row, writes, &errs, retrieveInt).(int64) @@ -1262,14 +1270,14 @@ func (s *sqlServerScraperHelper) recordDatabaseSampleQuery(ctx context.Context) timestamp, clientAddressVal, clientPortVal, dbNamespaceVal, queryTextVal, dbSystemNameVal, networkPeerAddressVal, networkPeerPortVal, - blockSessionIDVal, blockingStartTimeVal, contextInfoVal, + blockSessionIDVal, blockingStartTimeVal, clientAppNameVal, contextInfoVal, commandVal, cpuTimeSecondVal, deadlockPriorityVal, estimatedCompletionTimeSecondVal, lockTimeoutSecondVal, logicalReadsVal, openTransactionCountVal, percentCompleteVal, queryHashVal, queryPlanHashVal, queryStartVal, readsVal, requestStatusVal, resourceIDVal, resourceTypeVal, rowCountVal, - sessionIDVal, sessionStatusVal, + sessionDurationSecondVal, sessionStartedVal, sessionIDVal, sessionStatusVal, totalElapsedTimeSecondVal, transactionIDVal, transactionIsolationLevelVal, waitResourceVal, waitTimeSecondVal, waitTypeVal, writesVal, usernameVal, row[storedProcedureID], row[storedProcedureName], diff --git a/receiver/sqlserverreceiver/scraper_test.go b/receiver/sqlserverreceiver/scraper_test.go index a2961e018c394..08cad06fb2958 100644 --- a/receiver/sqlserverreceiver/scraper_test.go +++ b/receiver/sqlserverreceiver/scraper_test.go @@ -818,6 +818,9 @@ func buildQuerySampleRow(sessionID, blockingSessionID, command, statement string "query_plan_hash": "0x140210F64B788CB9", "context_info": "", "username": "sa", + "client_app_name": "SSMS", + "session_started": "2025-02-12T15:00:00.000+08:00", + "session_duration": "720456", "procedure_id": "0", "procedure_name": "", "blocking_start_time": "", diff --git a/receiver/sqlserverreceiver/templates/sqlServerIdleBlockerQuerySample.tmpl b/receiver/sqlserverreceiver/templates/sqlServerIdleBlockerQuerySample.tmpl index 0c2c3ac5845da..97d034f9ac64d 100644 --- a/receiver/sqlserverreceiver/templates/sqlServerIdleBlockerQuerySample.tmpl +++ b/receiver/sqlserverreceiver/templates/sqlServerIdleBlockerQuerySample.tmpl @@ -33,6 +33,9 @@ SELECT TOP(@top) CONVERT(VARBINARY, '') AS query_plan_hash, CONVERT(VARBINARY, '') AS context_info, s.login_name AS username, + ISNULL(s.program_name, '') AS client_app_name, + CONVERT(NVARCHAR, TODATETIMEOFFSET(s.login_time, DATEPART(TZOFFSET, SYSDATETIMEOFFSET())), 126) AS session_started, + s.total_elapsed_time AS session_duration, '' AS procedure_id, '' AS procedure_name FROM sys.dm_exec_sessions s diff --git a/receiver/sqlserverreceiver/templates/sqlServerQuerySample.tmpl b/receiver/sqlserverreceiver/templates/sqlServerQuerySample.tmpl index 58e3f592f1560..3f047f2ddb487 100644 --- a/receiver/sqlserverreceiver/templates/sqlServerQuerySample.tmpl +++ b/receiver/sqlserverreceiver/templates/sqlServerQuerySample.tmpl @@ -45,6 +45,9 @@ SELECT TOP(@top) ISNULL(r.query_plan_hash, CONVERT(VARBINARY, '')) AS query_plan_hash, ISNULL(r.context_info, CONVERT(VARBINARY, '')) AS context_info, s.login_name AS username, + ISNULL(s.program_name, '') AS client_app_name, + CONVERT(NVARCHAR, TODATETIMEOFFSET(s.login_time, DATEPART(TZOFFSET, SYSDATETIMEOFFSET())), 126) AS session_started, + s.total_elapsed_time AS session_duration, ISNULL(CASE WHEN o.objectid > 0 THEN o.objectid END, '') AS procedure_id, ISNULL(CASE WHEN o.objectid > 0 THEN QUOTENAME(OBJECT_SCHEMA_NAME(o.objectid, o.dbid)) diff --git a/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQuery.yaml b/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQuery.yaml index b5c779aeb6476..c6f4b580bf29c 100644 --- a/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQuery.yaml +++ b/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQuery.yaml @@ -49,6 +49,9 @@ resourceLogs: - key: sqlserver.blocking.start_time value: stringValue: "2025-02-12T16:37:52.393+08:00" + - key: sqlserver.client.app.name + value: + stringValue: SSMS - key: sqlserver.context_info value: stringValue: "" @@ -100,9 +103,15 @@ resourceLogs: - key: sqlserver.row_count value: intValue: "1" + - key: sqlserver.session.duration + value: + doubleValue: 720.456 - key: sqlserver.session_id value: intValue: "60" + - key: sqlserver.session.started + value: + stringValue: "2025-02-12T15:00:00.000+08:00" - key: sqlserver.session_status value: stringValue: running diff --git a/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQueryWithInvalidData.yaml b/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQueryWithInvalidData.yaml index a118452af89ca..63b99355f0c98 100644 --- a/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQueryWithInvalidData.yaml +++ b/receiver/sqlserverreceiver/testdata/expectedRecordDatabaseSampleQueryWithInvalidData.yaml @@ -46,6 +46,9 @@ resourceLogs: - key: sqlserver.blocking_session_id value: intValue: "0" + - key: sqlserver.client.app.name + value: + stringValue: SSMS - key: sqlserver.context_info value: stringValue: "307837304133423133304231303438443444" @@ -97,9 +100,15 @@ resourceLogs: - key: sqlserver.row_count value: intValue: "0" + - key: sqlserver.session.duration + value: + doubleValue: 0 - key: sqlserver.session_id value: intValue: "0" + - key: sqlserver.session.started + value: + stringValue: "2025-02-12T15:00:00.000+08:00" - key: sqlserver.session_status value: stringValue: running diff --git a/receiver/sqlserverreceiver/testdata/recordDatabaseSampleQueryData.txt b/receiver/sqlserverreceiver/testdata/recordDatabaseSampleQueryData.txt index 54c748dbd3fa9..30dbfc34ccc38 100644 --- a/receiver/sqlserverreceiver/testdata/recordDatabaseSampleQueryData.txt +++ b/receiver/sqlserverreceiver/testdata/recordDatabaseSampleQueryData.txt @@ -24,6 +24,7 @@ "percent_complete": "0", "estimated_completion_time": "0", "cpu_time": "6", + "session_duration": "720456", "total_elapsed_time": "6", "reads": "0", "writes": "0", @@ -36,6 +37,8 @@ "query_plan_hash": "0x140210F64B788CB9", "context_info": "00-0af7651916cd43dd8448eb211c80319c-a7ad6a7169203331-01", "username": "sa", + "client_app_name": "SSMS", + "session_started": "2025-02-12T15:00:00.000+08:00", "procedure_id": "0", "procedure_name": "" } diff --git a/receiver/sqlserverreceiver/testdata/recordInvalidDatabaseSampleQueryData.txt b/receiver/sqlserverreceiver/testdata/recordInvalidDatabaseSampleQueryData.txt index 0f147bebe40eb..4fda277109958 100644 --- a/receiver/sqlserverreceiver/testdata/recordInvalidDatabaseSampleQueryData.txt +++ b/receiver/sqlserverreceiver/testdata/recordInvalidDatabaseSampleQueryData.txt @@ -24,6 +24,7 @@ "percent_complete": "a0", "estimated_completion_time": "a0", "cpu_time": "a6", + "session_duration": "a720", "total_elapsed_time": "a6", "reads": "a0", "writes": "a0", @@ -36,6 +37,8 @@ "query_plan_hash": "0x140210F64B788CB9", "context_info": "0x70A3B130B1048D4D", "username": "sa", + "client_app_name": "SSMS", + "session_started": "2025-02-12T15:00:00.000+08:00", "procedure_id": "0", "procedure_name": "" } diff --git a/receiver/sqlserverreceiver/testdata/testIdleBlockerQuerySampleQuery.txt b/receiver/sqlserverreceiver/testdata/testIdleBlockerQuerySampleQuery.txt index 0c2c3ac5845da..97d034f9ac64d 100644 --- a/receiver/sqlserverreceiver/testdata/testIdleBlockerQuerySampleQuery.txt +++ b/receiver/sqlserverreceiver/testdata/testIdleBlockerQuerySampleQuery.txt @@ -33,6 +33,9 @@ SELECT TOP(@top) CONVERT(VARBINARY, '') AS query_plan_hash, CONVERT(VARBINARY, '') AS context_info, s.login_name AS username, + ISNULL(s.program_name, '') AS client_app_name, + CONVERT(NVARCHAR, TODATETIMEOFFSET(s.login_time, DATEPART(TZOFFSET, SYSDATETIMEOFFSET())), 126) AS session_started, + s.total_elapsed_time AS session_duration, '' AS procedure_id, '' AS procedure_name FROM sys.dm_exec_sessions s diff --git a/receiver/sqlserverreceiver/testdata/testQuerySampleQuery.txt b/receiver/sqlserverreceiver/testdata/testQuerySampleQuery.txt index 58e3f592f1560..3f047f2ddb487 100644 --- a/receiver/sqlserverreceiver/testdata/testQuerySampleQuery.txt +++ b/receiver/sqlserverreceiver/testdata/testQuerySampleQuery.txt @@ -45,6 +45,9 @@ SELECT TOP(@top) ISNULL(r.query_plan_hash, CONVERT(VARBINARY, '')) AS query_plan_hash, ISNULL(r.context_info, CONVERT(VARBINARY, '')) AS context_info, s.login_name AS username, + ISNULL(s.program_name, '') AS client_app_name, + CONVERT(NVARCHAR, TODATETIMEOFFSET(s.login_time, DATEPART(TZOFFSET, SYSDATETIMEOFFSET())), 126) AS session_started, + s.total_elapsed_time AS session_duration, ISNULL(CASE WHEN o.objectid > 0 THEN o.objectid END, '') AS procedure_id, ISNULL(CASE WHEN o.objectid > 0 THEN QUOTENAME(OBJECT_SCHEMA_NAME(o.objectid, o.dbid))