-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[receiver/oracledb] Fix incorrect values for a couple of metrics #32028
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Use this changelog template to create an entry for release notes. | ||
|
||
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' | ||
change_type: bug_fix | ||
|
||
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) | ||
component: oracledbreceiver | ||
|
||
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). | ||
note: Fix incorrect values being set for oracledb.tablespace_size.limit and oracledb.tablespace_size.usage | ||
|
||
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. | ||
issues: [31451] | ||
|
||
# (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: | ||
|
||
# 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: [] |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,8 +38,10 @@ const ( | |
consistentGets = "consistent gets" | ||
sessionCountSQL = "select status, type, count(*) as VALUE FROM v$session GROUP BY status, type" | ||
systemResourceLimitsSQL = "select RESOURCE_NAME, CURRENT_UTILIZATION, LIMIT_VALUE, CASE WHEN TRIM(INITIAL_ALLOCATION) LIKE 'UNLIMITED' THEN '-1' ELSE TRIM(INITIAL_ALLOCATION) END as INITIAL_ALLOCATION, CASE WHEN TRIM(LIMIT_VALUE) LIKE 'UNLIMITED' THEN '-1' ELSE TRIM(LIMIT_VALUE) END as LIMIT_VALUE from v$resource_limit" | ||
tablespaceUsageSQL = "select TABLESPACE_NAME, BYTES from DBA_DATA_FILES" | ||
tablespaceMaxSpaceSQL = "select TABLESPACE_NAME, (BLOCK_SIZE*MAX_EXTENTS) AS VALUE FROM DBA_TABLESPACES" | ||
tablespaceUsageSQL = ` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feedback on indentation here would be helpful, not sure what's the most clear here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was readable enough. I had a bit of hesitation that the query itself is 2 separate subqueries, joined via a where statement with a bigger query. It feels like an inner join could do the job, but my SQL is rusty and this is an improvement over the broken functionality. Maybe something to explore if it becomes a performance flare up, which I doubt. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair point. I added a benchmark test locally to compare this query vs. inner join, here are the results.
Two separate queries:
I'll update to use the inner join 👍 |
||
select um.TABLESPACE_NAME, um.USED_SPACE, um.TABLESPACE_SIZE, ts.BLOCK_SIZE | ||
FROM DBA_TABLESPACE_USAGE_METRICS um INNER JOIN DBA_TABLESPACES ts | ||
ON um.TABLESPACE_NAME = ts.TABLESPACE_NAME` | ||
) | ||
|
||
type dbProviderFunc func() (*sql.DB, error) | ||
|
@@ -48,7 +50,6 @@ type clientProviderFunc func(*sql.DB, string, *zap.Logger) dbClient | |
|
||
type scraper struct { | ||
statsClient dbClient | ||
tablespaceMaxSpaceClient dbClient | ||
tablespaceUsageClient dbClient | ||
systemResourceLimitsClient dbClient | ||
sessionCountClient dbClient | ||
|
@@ -88,7 +89,6 @@ func (s *scraper) start(context.Context, component.Host) error { | |
s.sessionCountClient = s.clientProviderFunc(s.db, sessionCountSQL, s.logger) | ||
s.systemResourceLimitsClient = s.clientProviderFunc(s.db, systemResourceLimitsSQL, s.logger) | ||
s.tablespaceUsageClient = s.clientProviderFunc(s.db, tablespaceUsageSQL, s.logger) | ||
s.tablespaceMaxSpaceClient = s.clientProviderFunc(s.db, tablespaceMaxSpaceSQL, s.logger) | ||
return nil | ||
} | ||
|
||
|
@@ -274,41 +274,49 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { | |
} | ||
} | ||
} | ||
if s.metricsBuilderConfig.Metrics.OracledbTablespaceSizeUsage.Enabled { | ||
|
||
if s.metricsBuilderConfig.Metrics.OracledbTablespaceSizeUsage.Enabled || | ||
s.metricsBuilderConfig.Metrics.OracledbTablespaceSizeLimit.Enabled { | ||
rows, err := s.tablespaceUsageClient.metricRows(ctx) | ||
if err != nil { | ||
scrapeErrors = append(scrapeErrors, fmt.Errorf("error executing %s: %w", tablespaceUsageSQL, err)) | ||
} else { | ||
now := pcommon.NewTimestampFromTime(time.Now()) | ||
for _, row := range rows { | ||
tablespaceName := row["TABLESPACE_NAME"] | ||
err := s.mb.RecordOracledbTablespaceSizeUsageDataPoint(now, row["BYTES"], tablespaceName) | ||
usedSpaceBlockCount, err := strconv.ParseInt(row["USED_SPACE"], 10, 64) | ||
if err != nil { | ||
scrapeErrors = append(scrapeErrors, err) | ||
scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse int64 for OracledbTablespaceSizeUsage, value was %s: %w", row["USED_SPACE"], err)) | ||
continue | ||
} | ||
} | ||
} | ||
} | ||
if s.metricsBuilderConfig.Metrics.OracledbTablespaceSizeLimit.Enabled { | ||
rows, err := s.tablespaceMaxSpaceClient.metricRows(ctx) | ||
if err != nil { | ||
scrapeErrors = append(scrapeErrors, fmt.Errorf("error executing %s: %w", tablespaceMaxSpaceSQL, err)) | ||
} else { | ||
now := pcommon.NewTimestampFromTime(time.Now()) | ||
for _, row := range rows { | ||
tablespaceName := row["TABLESPACE_NAME"] | ||
var val int64 | ||
inputVal := row["VALUE"] | ||
if inputVal == "" { | ||
val = -1 | ||
|
||
tablespaceSizeOriginal := row["TABLESPACE_SIZE"] | ||
var tablespaceSizeBlockCount int64 | ||
// Tablespace size should never be empty using the DBA_TABLESPACE_USAGE_METRICS query. This logic is done | ||
// to preserve backward compatibility for with the original metric gathered from querying DBA_TABLESPACES | ||
if tablespaceSizeOriginal == "" { | ||
tablespaceSizeBlockCount = -1 | ||
} else { | ||
val, err = strconv.ParseInt(inputVal, 10, 64) | ||
tablespaceSizeBlockCount, err = strconv.ParseInt(tablespaceSizeOriginal, 10, 64) | ||
if err != nil { | ||
scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse int64 for OracledbTablespaceSizeLimit, value was %s: %w", inputVal, err)) | ||
scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse int64 for OracledbTablespaceSizeLimit, value was %s: %w", tablespaceSizeOriginal, err)) | ||
continue | ||
} | ||
} | ||
s.mb.RecordOracledbTablespaceSizeLimitDataPoint(now, val, tablespaceName) | ||
|
||
blockSize, err := strconv.ParseInt(row["BLOCK_SIZE"], 10, 64) | ||
if err != nil { | ||
scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse int64 for OracledbBlockSize, value was %s: %w", row["BLOCK_SIZE"], err)) | ||
continue | ||
} | ||
|
||
s.mb.RecordOracledbTablespaceSizeUsageDataPoint(now, usedSpaceBlockCount*blockSize, tablespaceName) | ||
|
||
if tablespaceSizeBlockCount < 0 { | ||
s.mb.RecordOracledbTablespaceSizeLimitDataPoint(now, -1, tablespaceName) | ||
} else { | ||
s.mb.RecordOracledbTablespaceSizeLimitDataPoint(now, tablespaceSizeBlockCount*blockSize, tablespaceName) | ||
} | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for setting this metric's value now requires two DB values to be multiplied by each other. This means we have to manually convert both values to
int64
, multiply them, then use that result to set the value here. Converting back to string just to convert toint64
again is unnecessary, so I've removed this option.