Skip to content

Commit 4d7c359

Browse files
committed
Oracle topN collection interval implementation
1 parent 1ee197e commit 4d7c359

File tree

4 files changed

+41
-31
lines changed

4 files changed

+41
-31
lines changed

receiver/oracledbreceiver/config.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ type TopQueryCollection struct {
3333
MaxQuerySampleCount uint `mapstructure:"max_query_sample_count"`
3434
TopQueryCount uint `mapstructure:"top_query_count"`
3535
CollectionInterval time.Duration `mapstructure:"collection_interval"`
36-
LookbackTime time.Duration `mapstructure:"lookback_time"`
3736
}
3837

3938
type QuerySample struct {
@@ -109,10 +108,3 @@ func (c Config) Validate() error {
109108
}
110109
return allErrs
111110
}
112-
113-
func (cfg *Config) EffectiveLookbackTime() time.Duration {
114-
if cfg.LookbackTime <= 0 {
115-
return 2 * cfg.ControllerConfig.CollectionInterval
116-
}
117-
return cfg.LookbackTime
118-
}

receiver/oracledbreceiver/factory.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func createDefaultConfig() component.Config {
5050
TopQueryCollection: TopQueryCollection{
5151
MaxQuerySampleCount: 1000,
5252
TopQueryCount: 200,
53+
CollectionInterval: 10 * time.Second,
5354
},
5455
}
5556
}

receiver/oracledbreceiver/scraper.go

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"encoding/json"
1212
"errors"
1313
"fmt"
14+
"math"
1415
"net"
1516
"os"
1617
"sort"
@@ -134,20 +135,20 @@ type oracleScraper struct {
134135
querySampleCfg QuerySample
135136
serviceInstanceID string
136137
lastExecutionTimestamp time.Time
138+
lastQueryMetricsDBTime string
137139
}
138140

139141
func newScraper(metricsBuilder *metadata.MetricsBuilder, metricsBuilderConfig metadata.MetricsBuilderConfig, scrapeCfg scraperhelper.ControllerConfig, logger *zap.Logger, providerFunc dbProviderFunc, clientProviderFunc clientProviderFunc, instanceName, hostName string) (scraper.Metrics, error) {
140142
s := &oracleScraper{
141-
mb: metricsBuilder,
142-
metricsBuilderConfig: metricsBuilderConfig,
143-
scrapeCfg: scrapeCfg,
144-
logger: logger,
145-
dbProviderFunc: providerFunc,
146-
clientProviderFunc: clientProviderFunc,
147-
instanceName: instanceName,
148-
hostName: hostName,
149-
serviceInstanceID: getInstanceID(instanceName, logger),
150-
lastExecutionTimestamp: time.Unix(0, 0),
143+
mb: metricsBuilder,
144+
metricsBuilderConfig: metricsBuilderConfig,
145+
scrapeCfg: scrapeCfg,
146+
logger: logger,
147+
dbProviderFunc: providerFunc,
148+
clientProviderFunc: clientProviderFunc,
149+
instanceName: instanceName,
150+
hostName: hostName,
151+
serviceInstanceID: getInstanceID(instanceName, logger),
151152
}
152153
return scraper.NewMetrics(s.scrape, scraper.WithShutdown(s.shutdown), scraper.WithStart(s.start))
153154
}
@@ -531,8 +532,12 @@ func (s *oracleScraper) scrapeLogs(ctx context.Context) (plog.Logs, error) {
531532
var scrapeErrors []error
532533

533534
if s.logsBuilderConfig.Events.DbServerTopQuery.Enabled {
534-
if s.isTopNMetricsCollectionDue() {
535-
topNCollectionErrors := s.collectTopNMetricData(ctx, logs)
535+
currentCollectionTime := time.Now()
536+
537+
if int(math.Ceil(currentCollectionTime.Sub(s.lastExecutionTimestamp).Seconds())) < int(s.topQueryCollectCfg.CollectionInterval.Seconds()) {
538+
s.logger.Debug("Skipping the collection of top queries because the current time has not yet exceeded the last execution time plus the specified collection interval")
539+
} else {
540+
topNCollectionErrors := s.collectTopNMetricData(ctx, logs, currentCollectionTime)
536541
if topNCollectionErrors != nil {
537542
scrapeErrors = append(scrapeErrors, topNCollectionErrors)
538543
}
@@ -549,17 +554,13 @@ func (s *oracleScraper) scrapeLogs(ctx context.Context) (plog.Logs, error) {
549554
return logs, errors.Join(scrapeErrors...)
550555
}
551556

552-
func (s *oracleScraper) isTopNMetricsCollectionDue() bool {
553-
554-
}
555-
556-
func (s *oracleScraper) collectTopNMetricData(ctx context.Context, logs plog.Logs) error {
557+
func (s *oracleScraper) collectTopNMetricData(ctx context.Context, logs plog.Logs, collectionTime time.Time) error {
557558
var errs []error
558559
// get metrics and query texts from DB
559-
timestamp := pcommon.NewTimestampFromTime(time.Now())
560-
intervalSeconds := int(s.scrapeCfg.CollectionInterval.Seconds())
560+
lookbackTimeSeconds := s.calculateLookbackSeconds()
561+
561562
s.oracleQueryMetricsClient = s.clientProviderFunc(s.db, oracleQueryMetricsSQL, s.logger)
562-
metricRows, metricError := s.oracleQueryMetricsClient.metricRows(ctx, intervalSeconds, s.topQueryCollectCfg.MaxQuerySampleCount)
563+
metricRows, metricError := s.oracleQueryMetricsClient.metricRows(ctx, lookbackTimeSeconds, lookbackTimeSeconds, s.topQueryCollectCfg.MaxQuerySampleCount)
563564

564565
if metricError != nil {
565566
return fmt.Errorf("error executing oracleQueryMetricsSQL: %w", metricError)
@@ -625,6 +626,8 @@ func (s *oracleScraper) collectTopNMetricData(ctx context.Context, logs plog.Log
625626
// if cache updates is not equal to rows returned, that indicates there is problem somewhere
626627
s.logger.Debug("Cache update", zap.Int("update-count", cacheUpdates), zap.Int("new-size", s.metricCache.Len()))
627628

629+
s.lastExecutionTimestamp = collectionTime
630+
fmt.Println(">>>>>> time set")
628631
if len(hits) == 0 {
629632
s.logger.Info("No log records for this scrape")
630633
return errors.Join(errs...)
@@ -654,7 +657,7 @@ func (s *oracleScraper) collectTopNMetricData(ctx context.Context, logs plog.Log
654657
planString := string(planBytes)
655658

656659
s.lb.RecordDbServerTopQueryEvent(context.Background(),
657-
timestamp,
660+
pcommon.NewTimestampFromTime(collectionTime),
658661
dbSystemNameVal,
659662
s.hostName,
660663
hit.queryText,
@@ -880,3 +883,15 @@ func constructInstanceID(host, port, service string) string {
880883
}
881884
return fmt.Sprintf("%s:%s", host, port)
882885
}
886+
887+
func (s *oracleScraper) calculateLookbackSeconds() int {
888+
if s.lastExecutionTimestamp.IsZero() {
889+
return int(s.topQueryCollectCfg.CollectionInterval.Seconds())
890+
}
891+
892+
const vsqlRefreshLagSec = 10 * time.Second // Buffer to account for v$sql maximum refresh latency
893+
894+
return int(math.Ceil(time.Now().
895+
Add(vsqlRefreshLagSec).
896+
Sub(s.lastExecutionTimestamp).Seconds()))
897+
}

receiver/oracledbreceiver/templates/oracleQueryMetricsAndTextSql.tmpl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
/* otel-collector */ SELECT
2+
SYSDATE,
3+
SYSDATE - NUMTODSINTERVAL(:1, 'SECOND') AS START_POINT,
24
SQL_ID,
35
SQL_FULLTEXT,
46
CHILD_NUMBER,
@@ -20,5 +22,5 @@ DISK_READS,
2022
DIRECT_WRITES,
2123
DIRECT_READS
2224
FROM V$SQL
23-
WHERE LAST_ACTIVE_TIME >= SYSDATE - NUMTODSINTERVAL(:1, 'SECOND')
24-
FETCH FIRST :2 ROWS ONLY
25+
WHERE LAST_ACTIVE_TIME >= SYSDATE - NUMTODSINTERVAL(:2, 'SECOND')
26+
FETCH FIRST :3 ROWS ONLY

0 commit comments

Comments
 (0)