@@ -160,7 +160,7 @@ func (s *sqlServerScraperHelper) recordDatabaseIOMetrics(ctx context.Context) er
160
160
161
161
var errs []error
162
162
now := pcommon .NewTimestampFromTime (time .Now ())
163
- var val float64
163
+ var val any
164
164
for i , row := range rows {
165
165
rb := s .mb .NewResourceBuilder ()
166
166
rb .SetSqlserverComputerName (row [computerNameKey ])
@@ -169,20 +169,20 @@ func (s *sqlServerScraperHelper) recordDatabaseIOMetrics(ctx context.Context) er
169
169
rb .SetServerAddress (s .config .Server )
170
170
rb .SetServerPort (int64 (s .config .Port ))
171
171
172
- val , err = strconv . ParseFloat (row [ readLatencyMsKey ], 64 )
172
+ val , err = retrieveFloat (row , readLatencyMsKey )
173
173
if err != nil {
174
174
err = fmt .Errorf ("row %d: %w" , i , err )
175
175
errs = append (errs , err )
176
176
} else {
177
- s .mb .RecordSqlserverDatabaseLatencyDataPoint (now , val / 1e3 , row [physicalFilenameKey ], row [logicalFilenameKey ], row [fileTypeKey ], metadata .AttributeDirectionRead )
177
+ s .mb .RecordSqlserverDatabaseLatencyDataPoint (now , val .( float64 ) / 1e3 , row [physicalFilenameKey ], row [logicalFilenameKey ], row [fileTypeKey ], metadata .AttributeDirectionRead )
178
178
}
179
179
180
- val , err = strconv . ParseFloat (row [ writeLatencyMsKey ], 64 )
180
+ val , err = retrieveFloat (row , writeLatencyMsKey )
181
181
if err != nil {
182
182
err = fmt .Errorf ("row %d: %w" , i , err )
183
183
errs = append (errs , err )
184
184
} else {
185
- s .mb .RecordSqlserverDatabaseLatencyDataPoint (now , val / 1e3 , row [physicalFilenameKey ], row [logicalFilenameKey ], row [fileTypeKey ], metadata .AttributeDirectionWrite )
185
+ s .mb .RecordSqlserverDatabaseLatencyDataPoint (now , val .( float64 ) / 1e3 , row [physicalFilenameKey ], row [logicalFilenameKey ], row [fileTypeKey ], metadata .AttributeDirectionWrite )
186
186
}
187
187
188
188
errs = append (errs , s .mb .RecordSqlserverDatabaseOperationsDataPoint (now , row [readCountKey ], row [physicalFilenameKey ], row [logicalFilenameKey ], row [fileTypeKey ], metadata .AttributeDirectionRead ))
@@ -253,210 +253,210 @@ func (s *sqlServerScraperHelper) recordDatabasePerfCounterMetrics(ctx context.Co
253
253
254
254
switch row [counterKey ] {
255
255
case activeTempTables :
256
- val , err := strconv . ParseInt (row [ valueKey ], 10 , 64 )
256
+ val , err := retrieveInt (row , valueKey )
257
257
if err != nil {
258
258
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , activeTempTables )
259
259
errs = append (errs , err )
260
260
} else {
261
- s .mb .RecordSqlserverTableCountDataPoint (now , val , metadata .AttributeTableStateActive , metadata .AttributeTableStatusTemporary )
261
+ s .mb .RecordSqlserverTableCountDataPoint (now , val .( int64 ) , metadata .AttributeTableStateActive , metadata .AttributeTableStatusTemporary )
262
262
}
263
263
case backupRestoreThroughputPerSec :
264
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
264
+ val , err := retrieveFloat (row , valueKey )
265
265
if err != nil {
266
266
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , backupRestoreThroughputPerSec )
267
267
errs = append (errs , err )
268
268
} else {
269
- s .mb .RecordSqlserverDatabaseBackupOrRestoreRateDataPoint (now , val )
269
+ s .mb .RecordSqlserverDatabaseBackupOrRestoreRateDataPoint (now , val .( float64 ) )
270
270
}
271
271
case batchRequestRate :
272
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
272
+ val , err := retrieveFloat (row , valueKey )
273
273
if err != nil {
274
274
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , batchRequestRate )
275
275
errs = append (errs , err )
276
276
} else {
277
- s .mb .RecordSqlserverBatchRequestRateDataPoint (now , val )
277
+ s .mb .RecordSqlserverBatchRequestRateDataPoint (now , val .( float64 ) )
278
278
}
279
279
case bufferCacheHitRatio :
280
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
280
+ val , err := retrieveFloat (row , valueKey )
281
281
if err != nil {
282
282
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , bufferCacheHitRatio )
283
283
errs = append (errs , err )
284
284
} else {
285
- s .mb .RecordSqlserverPageBufferCacheHitRatioDataPoint (now , val )
285
+ s .mb .RecordSqlserverPageBufferCacheHitRatioDataPoint (now , val .( float64 ) )
286
286
}
287
287
case bytesReceivedFromReplicaPerSec :
288
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
288
+ val , err := retrieveFloat (row , valueKey )
289
289
if err != nil {
290
290
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , bytesReceivedFromReplicaPerSec )
291
291
errs = append (errs , err )
292
292
} else {
293
- s .mb .RecordSqlserverReplicaDataRateDataPoint (now , val , metadata .AttributeReplicaDirectionReceive )
293
+ s .mb .RecordSqlserverReplicaDataRateDataPoint (now , val .( float64 ) , metadata .AttributeReplicaDirectionReceive )
294
294
}
295
295
case bytesSentForReplicaPerSec :
296
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
296
+ val , err := retrieveFloat (row , valueKey )
297
297
if err != nil {
298
298
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , bytesReceivedFromReplicaPerSec )
299
299
errs = append (errs , err )
300
300
} else {
301
- s .mb .RecordSqlserverReplicaDataRateDataPoint (now , val , metadata .AttributeReplicaDirectionTransmit )
301
+ s .mb .RecordSqlserverReplicaDataRateDataPoint (now , val .( float64 ) , metadata .AttributeReplicaDirectionTransmit )
302
302
}
303
303
case diskReadIOThrottled :
304
304
errs = append (errs , s .mb .RecordSqlserverResourcePoolDiskThrottledReadRateDataPoint (now , row [valueKey ]))
305
305
case diskWriteIOThrottled :
306
306
errs = append (errs , s .mb .RecordSqlserverResourcePoolDiskThrottledWriteRateDataPoint (now , row [valueKey ]))
307
307
case executionErrors :
308
- val , err := strconv . ParseInt (row [ valueKey ], 10 , 64 )
308
+ val , err := retrieveInt (row , valueKey )
309
309
if err != nil {
310
310
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , executionErrors )
311
311
errs = append (errs , err )
312
312
} else {
313
- s .mb .RecordSqlserverDatabaseExecutionErrorsDataPoint (now , val )
313
+ s .mb .RecordSqlserverDatabaseExecutionErrorsDataPoint (now , val .( int64 ) )
314
314
}
315
315
case freeListStalls :
316
- val , err := strconv . ParseInt (row [ valueKey ], 10 , 64 )
316
+ val , err := retrieveInt (row , valueKey )
317
317
if err != nil {
318
318
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , freeListStalls )
319
319
errs = append (errs , err )
320
320
} else {
321
- s .mb .RecordSqlserverPageBufferCacheFreeListStallsRateDataPoint (now , val )
321
+ s .mb .RecordSqlserverPageBufferCacheFreeListStallsRateDataPoint (now , val .( int64 ) )
322
322
}
323
323
case fullScansPerSec :
324
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
324
+ val , err := retrieveFloat (row , valueKey )
325
325
if err != nil {
326
326
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , fullScansPerSec )
327
327
errs = append (errs , err )
328
328
} else {
329
- s .mb .RecordSqlserverDatabaseFullScanRateDataPoint (now , val )
329
+ s .mb .RecordSqlserverDatabaseFullScanRateDataPoint (now , val .( float64 ) )
330
330
}
331
331
case freeSpaceInTempdb :
332
- val , err := strconv . ParseInt (row [ valueKey ], 10 , 64 )
332
+ val , err := retrieveInt (row , valueKey )
333
333
if err != nil {
334
334
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , freeSpaceInTempdb )
335
335
errs = append (errs , err )
336
336
} else {
337
- s .mb .RecordSqlserverDatabaseTempdbSpaceDataPoint (now , val , metadata .AttributeTempdbStateFree )
337
+ s .mb .RecordSqlserverDatabaseTempdbSpaceDataPoint (now , val .( int64 ) , metadata .AttributeTempdbStateFree )
338
338
}
339
339
case indexSearchesPerSec :
340
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
340
+ val , err := retrieveFloat (row , valueKey )
341
341
if err != nil {
342
342
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , indexSearchesPerSec )
343
343
errs = append (errs , err )
344
344
} else {
345
- s .mb .RecordSqlserverIndexSearchRateDataPoint (now , val )
345
+ s .mb .RecordSqlserverIndexSearchRateDataPoint (now , val .( float64 ) )
346
346
}
347
347
case lockTimeoutsPerSec :
348
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
348
+ val , err := retrieveFloat (row , valueKey )
349
349
if err != nil {
350
350
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , lockTimeoutsPerSec )
351
351
errs = append (errs , err )
352
352
} else {
353
- s .mb .RecordSqlserverLockTimeoutRateDataPoint (now , val )
353
+ s .mb .RecordSqlserverLockTimeoutRateDataPoint (now , val .( float64 ) )
354
354
}
355
355
case lockWaits :
356
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
356
+ val , err := retrieveFloat (row , valueKey )
357
357
if err != nil {
358
358
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , lockWaits )
359
359
errs = append (errs , err )
360
360
} else {
361
- s .mb .RecordSqlserverLockWaitRateDataPoint (now , val )
361
+ s .mb .RecordSqlserverLockWaitRateDataPoint (now , val .( float64 ) )
362
362
}
363
363
case loginsPerSec :
364
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
364
+ val , err := retrieveFloat (row , valueKey )
365
365
if err != nil {
366
366
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , loginsPerSec )
367
367
errs = append (errs , err )
368
368
} else {
369
- s .mb .RecordSqlserverLoginRateDataPoint (now , val )
369
+ s .mb .RecordSqlserverLoginRateDataPoint (now , val .( float64 ) )
370
370
}
371
371
case logoutPerSec :
372
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
372
+ val , err := retrieveFloat (row , valueKey )
373
373
if err != nil {
374
374
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , logoutPerSec )
375
375
errs = append (errs , err )
376
376
} else {
377
- s .mb .RecordSqlserverLogoutRateDataPoint (now , val )
377
+ s .mb .RecordSqlserverLogoutRateDataPoint (now , val .( float64 ) )
378
378
}
379
379
case memoryGrantsPending :
380
- val , err := strconv . ParseInt (row [ valueKey ], 10 , 64 )
380
+ val , err := retrieveInt (row , valueKey )
381
381
if err != nil {
382
382
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , memoryGrantsPending )
383
383
errs = append (errs , err )
384
384
} else {
385
- s .mb .RecordSqlserverMemoryGrantsPendingCountDataPoint (now , val )
385
+ s .mb .RecordSqlserverMemoryGrantsPendingCountDataPoint (now , val .( int64 ) )
386
386
}
387
387
case mirrorWritesTransactionPerSec :
388
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
388
+ val , err := retrieveFloat (row , valueKey )
389
389
if err != nil {
390
390
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , mirrorWritesTransactionPerSec )
391
391
errs = append (errs , err )
392
392
} else {
393
- s .mb .RecordSqlserverTransactionMirrorWriteRateDataPoint (now , val )
393
+ s .mb .RecordSqlserverTransactionMirrorWriteRateDataPoint (now , val .( float64 ) )
394
394
}
395
395
case numberOfDeadlocksPerSec :
396
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
396
+ val , err := retrieveFloat (row , valueKey )
397
397
if err != nil {
398
398
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , numberOfDeadlocksPerSec )
399
399
errs = append (errs , err )
400
400
} else {
401
- s .mb .RecordSqlserverDeadlockRateDataPoint (now , val )
401
+ s .mb .RecordSqlserverDeadlockRateDataPoint (now , val .( float64 ) )
402
402
}
403
403
case pageLookupsPerSec :
404
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
404
+ val , err := retrieveFloat (row , valueKey )
405
405
if err != nil {
406
406
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , pageLookupsPerSec )
407
407
errs = append (errs , err )
408
408
} else {
409
- s .mb .RecordSqlserverPageLookupRateDataPoint (now , val )
409
+ s .mb .RecordSqlserverPageLookupRateDataPoint (now , val .( float64 ) )
410
410
}
411
411
case processesBlocked :
412
412
errs = append (errs , s .mb .RecordSqlserverProcessesBlockedDataPoint (now , row [valueKey ]))
413
413
case sqlCompilationRate :
414
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
414
+ val , err := retrieveFloat (row , valueKey )
415
415
if err != nil {
416
416
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , sqlCompilationRate )
417
417
errs = append (errs , err )
418
418
} else {
419
- s .mb .RecordSqlserverBatchSQLCompilationRateDataPoint (now , val )
419
+ s .mb .RecordSqlserverBatchSQLCompilationRateDataPoint (now , val .( float64 ) )
420
420
}
421
421
case sqlReCompilationsRate :
422
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
422
+ val , err := retrieveFloat (row , valueKey )
423
423
if err != nil {
424
424
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , sqlReCompilationsRate )
425
425
errs = append (errs , err )
426
426
} else {
427
- s .mb .RecordSqlserverBatchSQLRecompilationRateDataPoint (now , val )
427
+ s .mb .RecordSqlserverBatchSQLRecompilationRateDataPoint (now , val .( float64 ) )
428
428
}
429
429
case transactionDelay :
430
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
430
+ val , err := retrieveFloat (row , valueKey )
431
431
if err != nil {
432
432
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , transactionDelay )
433
433
errs = append (errs , err )
434
434
} else {
435
- s .mb .RecordSqlserverTransactionDelayDataPoint (now , val )
435
+ s .mb .RecordSqlserverTransactionDelayDataPoint (now , val .( float64 ) )
436
436
}
437
437
case userConnCount :
438
- val , err := strconv . ParseInt (row [ valueKey ], 10 , 64 )
438
+ val , err := retrieveInt (row , valueKey )
439
439
if err != nil {
440
440
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , userConnCount )
441
441
errs = append (errs , err )
442
442
} else {
443
- s .mb .RecordSqlserverUserConnectionCountDataPoint (now , val )
443
+ s .mb .RecordSqlserverUserConnectionCountDataPoint (now , val .( int64 ) )
444
444
}
445
445
case usedMemory :
446
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
446
+ val , err := retrieveFloat (row , valueKey )
447
447
if err != nil {
448
448
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , usedMemory )
449
449
errs = append (errs , err )
450
450
} else {
451
- s .mb .RecordSqlserverMemoryUsageDataPoint (now , val )
451
+ s .mb .RecordSqlserverMemoryUsageDataPoint (now , val .( float64 ) )
452
452
}
453
453
case versionStoreSize :
454
- val , err := strconv . ParseFloat (row [ valueKey ], 64 )
454
+ val , err := retrieveFloat (row , valueKey )
455
455
if err != nil {
456
456
err = fmt .Errorf ("failed to parse valueKey for row %d: %w in %s" , i , err , versionStoreSize )
457
457
errs = append (errs , err )
458
458
} else {
459
- s .mb .RecordSqlserverDatabaseTempdbVersionStoreSizeDataPoint (now , val )
459
+ s .mb .RecordSqlserverDatabaseTempdbVersionStoreSizeDataPoint (now , val .( float64 ) )
460
460
}
461
461
}
462
462
@@ -831,11 +831,25 @@ func vanillaRetriever(row sqlquery.StringMap, columnName string) (any, error) {
831
831
832
832
func retrieveInt (row sqlquery.StringMap , columnName string ) (any , error ) {
833
833
var err error
834
- result := 0
834
+ var result int64
835
835
if row [columnName ] != "" {
836
- result , err = strconv .Atoi (row [columnName ])
836
+ result , err = strconv .ParseInt (row [columnName ], 10 , 64 )
837
+ if err != nil {
838
+ // SQL Server stores large integers in scientific e notation
839
+ // (eg 123456 is stored as 1.23456e+5)
840
+ // This value cannot be parsed by strconv.ParseInt, but is successfully
841
+ // parsed by strconv.ParseFloat. The goal is here to convert to int
842
+ // even if the stored value is in scientific e notation.
843
+ var resultFloat float64
844
+ resultFloat , err = strconv .ParseFloat (row [columnName ], 64 )
845
+ if err == nil {
846
+ result = int64 (resultFloat )
847
+ }
848
+ }
849
+ } else {
850
+ err = fmt .Errorf ("no value found for column %s" , columnName )
837
851
}
838
- return int64 ( result ) , err
852
+ return result , err
839
853
}
840
854
841
855
func retrieveIntAndConvert (convert func (int64 ) any ) func (row sqlquery.StringMap , columnName string ) (any , error ) {
@@ -851,6 +865,8 @@ func retrieveFloat(row sqlquery.StringMap, columnName string) (any, error) {
851
865
var result float64
852
866
if row [columnName ] != "" {
853
867
result , err = strconv .ParseFloat (row [columnName ], 64 )
868
+ } else {
869
+ err = fmt .Errorf ("no value found for column %s" , columnName )
854
870
}
855
871
return result , err
856
872
}
0 commit comments