diff --git a/.chloggen/splunkenterprisereceiver-search-artifacts.yaml b/.chloggen/splunkenterprisereceiver-search-artifacts.yaml new file mode 100644 index 000000000000..0d3505e00dd6 --- /dev/null +++ b/.chloggen/splunkenterprisereceiver-search-artifacts.yaml @@ -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: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: splunkenterprisereceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add new metrics for Splunk Enterprise dispatch artifacts + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [35950] + +# (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: [user] diff --git a/receiver/splunkenterprisereceiver/documentation.md b/receiver/splunkenterprisereceiver/documentation.md index 18671d969bc2..e866054e5627 100644 --- a/receiver/splunkenterprisereceiver/documentation.md +++ b/receiver/splunkenterprisereceiver/documentation.md @@ -475,3 +475,87 @@ Gauge tracking current bytes waiting in queue. *Note:** Must be pointed at speci | Name | Description | Values | | ---- | ----------- | ------ | | splunk.queue.name | The name of the queue reporting a specific KPI | Any Str | + +### splunk.server.searchartifacts.adhoc + +Gauge tracking number of ad hoc search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {search_artifacts} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| splunk.host | The name of the splunk host | Any Str | + +### splunk.server.searchartifacts.completed + +Gauge tracking number of artifacts currently on disk that belong to finished searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {search_artifacts} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| splunk.host | The name of the splunk host | Any Str | + +### splunk.server.searchartifacts.incomplete + +Gauge tracking number of artifacts currently on disk that belong to unfinished/running searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {search_artifacts} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| splunk.host | The name of the splunk host | Any Str | + +### splunk.server.searchartifacts.invalid + +Gauge tracking number of artifacts currently on disk that are not in a valid state, such as missing info.csv file, etc. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {search_artifacts} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| splunk.host | The name of the splunk host | Any Str | + +### splunk.server.searchartifacts.savedsearches + +Gauge tracking, for the `splunk.server.searchartifacts.scheduled` number of scheduled search artifacts, how many different saved-searches they belong to. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {search_artifacts} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| splunk.host | The name of the splunk host | Any Str | + +### splunk.server.searchartifacts.scheduled + +Gauge tracking number of scheduled search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {search_artifacts} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| splunk.host | The name of the splunk host | Any Str | diff --git a/receiver/splunkenterprisereceiver/internal/metadata/generated_config.go b/receiver/splunkenterprisereceiver/internal/metadata/generated_config.go index 4887e11ff0b0..9daf22b30999 100644 --- a/receiver/splunkenterprisereceiver/internal/metadata/generated_config.go +++ b/receiver/splunkenterprisereceiver/internal/metadata/generated_config.go @@ -58,6 +58,12 @@ type MetricsConfig struct { SplunkSchedulerCompletionRatio MetricConfig `mapstructure:"splunk.scheduler.completion.ratio"` SplunkServerIntrospectionQueuesCurrent MetricConfig `mapstructure:"splunk.server.introspection.queues.current"` SplunkServerIntrospectionQueuesCurrentBytes MetricConfig `mapstructure:"splunk.server.introspection.queues.current.bytes"` + SplunkServerSearchartifactsAdhoc MetricConfig `mapstructure:"splunk.server.searchartifacts.adhoc"` + SplunkServerSearchartifactsCompleted MetricConfig `mapstructure:"splunk.server.searchartifacts.completed"` + SplunkServerSearchartifactsIncomplete MetricConfig `mapstructure:"splunk.server.searchartifacts.incomplete"` + SplunkServerSearchartifactsInvalid MetricConfig `mapstructure:"splunk.server.searchartifacts.invalid"` + SplunkServerSearchartifactsSavedsearches MetricConfig `mapstructure:"splunk.server.searchartifacts.savedsearches"` + SplunkServerSearchartifactsScheduled MetricConfig `mapstructure:"splunk.server.searchartifacts.scheduled"` SplunkTypingQueueRatio MetricConfig `mapstructure:"splunk.typing.queue.ratio"` } @@ -156,6 +162,24 @@ func DefaultMetricsConfig() MetricsConfig { SplunkServerIntrospectionQueuesCurrentBytes: MetricConfig{ Enabled: false, }, + SplunkServerSearchartifactsAdhoc: MetricConfig{ + Enabled: false, + }, + SplunkServerSearchartifactsCompleted: MetricConfig{ + Enabled: false, + }, + SplunkServerSearchartifactsIncomplete: MetricConfig{ + Enabled: false, + }, + SplunkServerSearchartifactsInvalid: MetricConfig{ + Enabled: false, + }, + SplunkServerSearchartifactsSavedsearches: MetricConfig{ + Enabled: false, + }, + SplunkServerSearchartifactsScheduled: MetricConfig{ + Enabled: false, + }, SplunkTypingQueueRatio: MetricConfig{ Enabled: true, }, diff --git a/receiver/splunkenterprisereceiver/internal/metadata/generated_config_test.go b/receiver/splunkenterprisereceiver/internal/metadata/generated_config_test.go index d904af8f5963..9b1dc2b53099 100644 --- a/receiver/splunkenterprisereceiver/internal/metadata/generated_config_test.go +++ b/receiver/splunkenterprisereceiver/internal/metadata/generated_config_test.go @@ -56,6 +56,12 @@ func TestMetricsBuilderConfig(t *testing.T) { SplunkSchedulerCompletionRatio: MetricConfig{Enabled: true}, SplunkServerIntrospectionQueuesCurrent: MetricConfig{Enabled: true}, SplunkServerIntrospectionQueuesCurrentBytes: MetricConfig{Enabled: true}, + SplunkServerSearchartifactsAdhoc: MetricConfig{Enabled: true}, + SplunkServerSearchartifactsCompleted: MetricConfig{Enabled: true}, + SplunkServerSearchartifactsIncomplete: MetricConfig{Enabled: true}, + SplunkServerSearchartifactsInvalid: MetricConfig{Enabled: true}, + SplunkServerSearchartifactsSavedsearches: MetricConfig{Enabled: true}, + SplunkServerSearchartifactsScheduled: MetricConfig{Enabled: true}, SplunkTypingQueueRatio: MetricConfig{Enabled: true}, }, }, @@ -95,6 +101,12 @@ func TestMetricsBuilderConfig(t *testing.T) { SplunkSchedulerCompletionRatio: MetricConfig{Enabled: false}, SplunkServerIntrospectionQueuesCurrent: MetricConfig{Enabled: false}, SplunkServerIntrospectionQueuesCurrentBytes: MetricConfig{Enabled: false}, + SplunkServerSearchartifactsAdhoc: MetricConfig{Enabled: false}, + SplunkServerSearchartifactsCompleted: MetricConfig{Enabled: false}, + SplunkServerSearchartifactsIncomplete: MetricConfig{Enabled: false}, + SplunkServerSearchartifactsInvalid: MetricConfig{Enabled: false}, + SplunkServerSearchartifactsSavedsearches: MetricConfig{Enabled: false}, + SplunkServerSearchartifactsScheduled: MetricConfig{Enabled: false}, SplunkTypingQueueRatio: MetricConfig{Enabled: false}, }, }, diff --git a/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics.go b/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics.go index 21a081c6031c..968f9b26bed2 100644 --- a/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics.go +++ b/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics.go @@ -1598,6 +1598,312 @@ func newMetricSplunkServerIntrospectionQueuesCurrentBytes(cfg MetricConfig) metr return m } +type metricSplunkServerSearchartifactsAdhoc struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills splunk.server.searchartifacts.adhoc metric with initial data. +func (m *metricSplunkServerSearchartifactsAdhoc) init() { + m.data.SetName("splunk.server.searchartifacts.adhoc") + m.data.SetDescription("Gauge tracking number of ad hoc search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.") + m.data.SetUnit("{search_artifacts}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricSplunkServerSearchartifactsAdhoc) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("splunk.host", splunkHostAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSplunkServerSearchartifactsAdhoc) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricSplunkServerSearchartifactsAdhoc) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSplunkServerSearchartifactsAdhoc(cfg MetricConfig) metricSplunkServerSearchartifactsAdhoc { + m := metricSplunkServerSearchartifactsAdhoc{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSplunkServerSearchartifactsCompleted struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills splunk.server.searchartifacts.completed metric with initial data. +func (m *metricSplunkServerSearchartifactsCompleted) init() { + m.data.SetName("splunk.server.searchartifacts.completed") + m.data.SetDescription("Gauge tracking number of artifacts currently on disk that belong to finished searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.") + m.data.SetUnit("{search_artifacts}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricSplunkServerSearchartifactsCompleted) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("splunk.host", splunkHostAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSplunkServerSearchartifactsCompleted) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricSplunkServerSearchartifactsCompleted) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSplunkServerSearchartifactsCompleted(cfg MetricConfig) metricSplunkServerSearchartifactsCompleted { + m := metricSplunkServerSearchartifactsCompleted{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSplunkServerSearchartifactsIncomplete struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills splunk.server.searchartifacts.incomplete metric with initial data. +func (m *metricSplunkServerSearchartifactsIncomplete) init() { + m.data.SetName("splunk.server.searchartifacts.incomplete") + m.data.SetDescription("Gauge tracking number of artifacts currently on disk that belong to unfinished/running searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.") + m.data.SetUnit("{search_artifacts}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricSplunkServerSearchartifactsIncomplete) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("splunk.host", splunkHostAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSplunkServerSearchartifactsIncomplete) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricSplunkServerSearchartifactsIncomplete) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSplunkServerSearchartifactsIncomplete(cfg MetricConfig) metricSplunkServerSearchartifactsIncomplete { + m := metricSplunkServerSearchartifactsIncomplete{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSplunkServerSearchartifactsInvalid struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills splunk.server.searchartifacts.invalid metric with initial data. +func (m *metricSplunkServerSearchartifactsInvalid) init() { + m.data.SetName("splunk.server.searchartifacts.invalid") + m.data.SetDescription("Gauge tracking number of artifacts currently on disk that are not in a valid state, such as missing info.csv file, etc. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.") + m.data.SetUnit("{search_artifacts}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricSplunkServerSearchartifactsInvalid) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("splunk.host", splunkHostAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSplunkServerSearchartifactsInvalid) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricSplunkServerSearchartifactsInvalid) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSplunkServerSearchartifactsInvalid(cfg MetricConfig) metricSplunkServerSearchartifactsInvalid { + m := metricSplunkServerSearchartifactsInvalid{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSplunkServerSearchartifactsSavedsearches struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills splunk.server.searchartifacts.savedsearches metric with initial data. +func (m *metricSplunkServerSearchartifactsSavedsearches) init() { + m.data.SetName("splunk.server.searchartifacts.savedsearches") + m.data.SetDescription("Gauge tracking, for the `splunk.server.searchartifacts.scheduled` number of scheduled search artifacts, how many different saved-searches they belong to. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.") + m.data.SetUnit("{search_artifacts}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricSplunkServerSearchartifactsSavedsearches) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("splunk.host", splunkHostAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSplunkServerSearchartifactsSavedsearches) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricSplunkServerSearchartifactsSavedsearches) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSplunkServerSearchartifactsSavedsearches(cfg MetricConfig) metricSplunkServerSearchartifactsSavedsearches { + m := metricSplunkServerSearchartifactsSavedsearches{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricSplunkServerSearchartifactsScheduled struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills splunk.server.searchartifacts.scheduled metric with initial data. +func (m *metricSplunkServerSearchartifactsScheduled) init() { + m.data.SetName("splunk.server.searchartifacts.scheduled") + m.data.SetDescription("Gauge tracking number of scheduled search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.") + m.data.SetUnit("{search_artifacts}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricSplunkServerSearchartifactsScheduled) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("splunk.host", splunkHostAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricSplunkServerSearchartifactsScheduled) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricSplunkServerSearchartifactsScheduled) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricSplunkServerSearchartifactsScheduled(cfg MetricConfig) metricSplunkServerSearchartifactsScheduled { + m := metricSplunkServerSearchartifactsScheduled{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricSplunkTypingQueueRatio struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -1688,6 +1994,12 @@ type MetricsBuilder struct { metricSplunkSchedulerCompletionRatio metricSplunkSchedulerCompletionRatio metricSplunkServerIntrospectionQueuesCurrent metricSplunkServerIntrospectionQueuesCurrent metricSplunkServerIntrospectionQueuesCurrentBytes metricSplunkServerIntrospectionQueuesCurrentBytes + metricSplunkServerSearchartifactsAdhoc metricSplunkServerSearchartifactsAdhoc + metricSplunkServerSearchartifactsCompleted metricSplunkServerSearchartifactsCompleted + metricSplunkServerSearchartifactsIncomplete metricSplunkServerSearchartifactsIncomplete + metricSplunkServerSearchartifactsInvalid metricSplunkServerSearchartifactsInvalid + metricSplunkServerSearchartifactsSavedsearches metricSplunkServerSearchartifactsSavedsearches + metricSplunkServerSearchartifactsScheduled metricSplunkServerSearchartifactsScheduled metricSplunkTypingQueueRatio metricSplunkTypingQueueRatio } @@ -1746,6 +2058,12 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricSplunkSchedulerCompletionRatio: newMetricSplunkSchedulerCompletionRatio(mbc.Metrics.SplunkSchedulerCompletionRatio), metricSplunkServerIntrospectionQueuesCurrent: newMetricSplunkServerIntrospectionQueuesCurrent(mbc.Metrics.SplunkServerIntrospectionQueuesCurrent), metricSplunkServerIntrospectionQueuesCurrentBytes: newMetricSplunkServerIntrospectionQueuesCurrentBytes(mbc.Metrics.SplunkServerIntrospectionQueuesCurrentBytes), + metricSplunkServerSearchartifactsAdhoc: newMetricSplunkServerSearchartifactsAdhoc(mbc.Metrics.SplunkServerSearchartifactsAdhoc), + metricSplunkServerSearchartifactsCompleted: newMetricSplunkServerSearchartifactsCompleted(mbc.Metrics.SplunkServerSearchartifactsCompleted), + metricSplunkServerSearchartifactsIncomplete: newMetricSplunkServerSearchartifactsIncomplete(mbc.Metrics.SplunkServerSearchartifactsIncomplete), + metricSplunkServerSearchartifactsInvalid: newMetricSplunkServerSearchartifactsInvalid(mbc.Metrics.SplunkServerSearchartifactsInvalid), + metricSplunkServerSearchartifactsSavedsearches: newMetricSplunkServerSearchartifactsSavedsearches(mbc.Metrics.SplunkServerSearchartifactsSavedsearches), + metricSplunkServerSearchartifactsScheduled: newMetricSplunkServerSearchartifactsScheduled(mbc.Metrics.SplunkServerSearchartifactsScheduled), metricSplunkTypingQueueRatio: newMetricSplunkTypingQueueRatio(mbc.Metrics.SplunkTypingQueueRatio), } @@ -1843,6 +2161,12 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricSplunkSchedulerCompletionRatio.emit(ils.Metrics()) mb.metricSplunkServerIntrospectionQueuesCurrent.emit(ils.Metrics()) mb.metricSplunkServerIntrospectionQueuesCurrentBytes.emit(ils.Metrics()) + mb.metricSplunkServerSearchartifactsAdhoc.emit(ils.Metrics()) + mb.metricSplunkServerSearchartifactsCompleted.emit(ils.Metrics()) + mb.metricSplunkServerSearchartifactsIncomplete.emit(ils.Metrics()) + mb.metricSplunkServerSearchartifactsInvalid.emit(ils.Metrics()) + mb.metricSplunkServerSearchartifactsSavedsearches.emit(ils.Metrics()) + mb.metricSplunkServerSearchartifactsScheduled.emit(ils.Metrics()) mb.metricSplunkTypingQueueRatio.emit(ils.Metrics()) for _, op := range options { @@ -2020,6 +2344,36 @@ func (mb *MetricsBuilder) RecordSplunkServerIntrospectionQueuesCurrentBytesDataP mb.metricSplunkServerIntrospectionQueuesCurrentBytes.recordDataPoint(mb.startTime, ts, val, splunkQueueNameAttributeValue) } +// RecordSplunkServerSearchartifactsAdhocDataPoint adds a data point to splunk.server.searchartifacts.adhoc metric. +func (mb *MetricsBuilder) RecordSplunkServerSearchartifactsAdhocDataPoint(ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + mb.metricSplunkServerSearchartifactsAdhoc.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) +} + +// RecordSplunkServerSearchartifactsCompletedDataPoint adds a data point to splunk.server.searchartifacts.completed metric. +func (mb *MetricsBuilder) RecordSplunkServerSearchartifactsCompletedDataPoint(ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + mb.metricSplunkServerSearchartifactsCompleted.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) +} + +// RecordSplunkServerSearchartifactsIncompleteDataPoint adds a data point to splunk.server.searchartifacts.incomplete metric. +func (mb *MetricsBuilder) RecordSplunkServerSearchartifactsIncompleteDataPoint(ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + mb.metricSplunkServerSearchartifactsIncomplete.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) +} + +// RecordSplunkServerSearchartifactsInvalidDataPoint adds a data point to splunk.server.searchartifacts.invalid metric. +func (mb *MetricsBuilder) RecordSplunkServerSearchartifactsInvalidDataPoint(ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + mb.metricSplunkServerSearchartifactsInvalid.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) +} + +// RecordSplunkServerSearchartifactsSavedsearchesDataPoint adds a data point to splunk.server.searchartifacts.savedsearches metric. +func (mb *MetricsBuilder) RecordSplunkServerSearchartifactsSavedsearchesDataPoint(ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + mb.metricSplunkServerSearchartifactsSavedsearches.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) +} + +// RecordSplunkServerSearchartifactsScheduledDataPoint adds a data point to splunk.server.searchartifacts.scheduled metric. +func (mb *MetricsBuilder) RecordSplunkServerSearchartifactsScheduledDataPoint(ts pcommon.Timestamp, val int64, splunkHostAttributeValue string) { + mb.metricSplunkServerSearchartifactsScheduled.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) +} + // RecordSplunkTypingQueueRatioDataPoint adds a data point to splunk.typing.queue.ratio metric. func (mb *MetricsBuilder) RecordSplunkTypingQueueRatioDataPoint(ts pcommon.Timestamp, val float64, splunkHostAttributeValue string) { mb.metricSplunkTypingQueueRatio.recordDataPoint(mb.startTime, ts, val, splunkHostAttributeValue) diff --git a/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics_test.go b/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics_test.go index 1e225a521ac8..b2c7ede854dc 100644 --- a/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/splunkenterprisereceiver/internal/metadata/generated_metrics_test.go @@ -170,6 +170,24 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSplunkServerIntrospectionQueuesCurrentBytesDataPoint(ts, 1, "splunk.queue.name-val") + allMetricsCount++ + mb.RecordSplunkServerSearchartifactsAdhocDataPoint(ts, 1, "splunk.host-val") + + allMetricsCount++ + mb.RecordSplunkServerSearchartifactsCompletedDataPoint(ts, 1, "splunk.host-val") + + allMetricsCount++ + mb.RecordSplunkServerSearchartifactsIncompleteDataPoint(ts, 1, "splunk.host-val") + + allMetricsCount++ + mb.RecordSplunkServerSearchartifactsInvalidDataPoint(ts, 1, "splunk.host-val") + + allMetricsCount++ + mb.RecordSplunkServerSearchartifactsSavedsearchesDataPoint(ts, 1, "splunk.host-val") + + allMetricsCount++ + mb.RecordSplunkServerSearchartifactsScheduledDataPoint(ts, 1, "splunk.host-val") + defaultMetricsCount++ allMetricsCount++ mb.RecordSplunkTypingQueueRatioDataPoint(ts, 1, "splunk.host-val") @@ -679,6 +697,96 @@ func TestMetricsBuilder(t *testing.T) { attrVal, ok := dp.Attributes().Get("splunk.queue.name") assert.True(t, ok) assert.EqualValues(t, "splunk.queue.name-val", attrVal.Str()) + case "splunk.server.searchartifacts.adhoc": + assert.False(t, validatedMetrics["splunk.server.searchartifacts.adhoc"], "Found a duplicate in the metrics slice: splunk.server.searchartifacts.adhoc") + validatedMetrics["splunk.server.searchartifacts.adhoc"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Gauge tracking number of ad hoc search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.", ms.At(i).Description()) + assert.Equal(t, "{search_artifacts}", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("splunk.host") + assert.True(t, ok) + assert.EqualValues(t, "splunk.host-val", attrVal.Str()) + case "splunk.server.searchartifacts.completed": + assert.False(t, validatedMetrics["splunk.server.searchartifacts.completed"], "Found a duplicate in the metrics slice: splunk.server.searchartifacts.completed") + validatedMetrics["splunk.server.searchartifacts.completed"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Gauge tracking number of artifacts currently on disk that belong to finished searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.", ms.At(i).Description()) + assert.Equal(t, "{search_artifacts}", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("splunk.host") + assert.True(t, ok) + assert.EqualValues(t, "splunk.host-val", attrVal.Str()) + case "splunk.server.searchartifacts.incomplete": + assert.False(t, validatedMetrics["splunk.server.searchartifacts.incomplete"], "Found a duplicate in the metrics slice: splunk.server.searchartifacts.incomplete") + validatedMetrics["splunk.server.searchartifacts.incomplete"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Gauge tracking number of artifacts currently on disk that belong to unfinished/running searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.", ms.At(i).Description()) + assert.Equal(t, "{search_artifacts}", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("splunk.host") + assert.True(t, ok) + assert.EqualValues(t, "splunk.host-val", attrVal.Str()) + case "splunk.server.searchartifacts.invalid": + assert.False(t, validatedMetrics["splunk.server.searchartifacts.invalid"], "Found a duplicate in the metrics slice: splunk.server.searchartifacts.invalid") + validatedMetrics["splunk.server.searchartifacts.invalid"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Gauge tracking number of artifacts currently on disk that are not in a valid state, such as missing info.csv file, etc. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.", ms.At(i).Description()) + assert.Equal(t, "{search_artifacts}", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("splunk.host") + assert.True(t, ok) + assert.EqualValues(t, "splunk.host-val", attrVal.Str()) + case "splunk.server.searchartifacts.savedsearches": + assert.False(t, validatedMetrics["splunk.server.searchartifacts.savedsearches"], "Found a duplicate in the metrics slice: splunk.server.searchartifacts.savedsearches") + validatedMetrics["splunk.server.searchartifacts.savedsearches"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Gauge tracking, for the `splunk.server.searchartifacts.scheduled` number of scheduled search artifacts, how many different saved-searches they belong to. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.", ms.At(i).Description()) + assert.Equal(t, "{search_artifacts}", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("splunk.host") + assert.True(t, ok) + assert.EqualValues(t, "splunk.host-val", attrVal.Str()) + case "splunk.server.searchartifacts.scheduled": + assert.False(t, validatedMetrics["splunk.server.searchartifacts.scheduled"], "Found a duplicate in the metrics slice: splunk.server.searchartifacts.scheduled") + validatedMetrics["splunk.server.searchartifacts.scheduled"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Gauge tracking number of scheduled search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head.", ms.At(i).Description()) + assert.Equal(t, "{search_artifacts}", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("splunk.host") + assert.True(t, ok) + assert.EqualValues(t, "splunk.host-val", attrVal.Str()) case "splunk.typing.queue.ratio": assert.False(t, validatedMetrics["splunk.typing.queue.ratio"], "Found a duplicate in the metrics slice: splunk.typing.queue.ratio") validatedMetrics["splunk.typing.queue.ratio"] = true diff --git a/receiver/splunkenterprisereceiver/internal/metadata/testdata/config.yaml b/receiver/splunkenterprisereceiver/internal/metadata/testdata/config.yaml index c3e150597d16..449cd89b2255 100644 --- a/receiver/splunkenterprisereceiver/internal/metadata/testdata/config.yaml +++ b/receiver/splunkenterprisereceiver/internal/metadata/testdata/config.yaml @@ -63,6 +63,18 @@ all_set: enabled: true splunk.server.introspection.queues.current.bytes: enabled: true + splunk.server.searchartifacts.adhoc: + enabled: true + splunk.server.searchartifacts.completed: + enabled: true + splunk.server.searchartifacts.incomplete: + enabled: true + splunk.server.searchartifacts.invalid: + enabled: true + splunk.server.searchartifacts.savedsearches: + enabled: true + splunk.server.searchartifacts.scheduled: + enabled: true splunk.typing.queue.ratio: enabled: true none_set: @@ -129,5 +141,17 @@ none_set: enabled: false splunk.server.introspection.queues.current.bytes: enabled: false + splunk.server.searchartifacts.adhoc: + enabled: false + splunk.server.searchartifacts.completed: + enabled: false + splunk.server.searchartifacts.incomplete: + enabled: false + splunk.server.searchartifacts.invalid: + enabled: false + splunk.server.searchartifacts.savedsearches: + enabled: false + splunk.server.searchartifacts.scheduled: + enabled: false splunk.typing.queue.ratio: enabled: false diff --git a/receiver/splunkenterprisereceiver/metadata.yaml b/receiver/splunkenterprisereceiver/metadata.yaml index 4c4c23b2c8e9..e6329f500e0d 100644 --- a/receiver/splunkenterprisereceiver/metadata.yaml +++ b/receiver/splunkenterprisereceiver/metadata.yaml @@ -231,8 +231,8 @@ metrics: unit: '{buckets}' gauge: value_type: int - attributes: [splunk.index.name, splunk.bucket.dir] - #'services/server/introspection/queues' + attributes: [splunk.index.name, splunk.bucket.dir] + #'services/server/introspection/queues' splunk.server.introspection.queues.current: enabled: false description: Gauge tracking current length of queue. *Note:** Must be pointed at specific indexer `endpoint` and gathers metrics from only that indexer. @@ -268,7 +268,62 @@ metrics: unit: '{status}' gauge: value_type: int - attributes: [splunk.kvstore.status.value] + attributes: [splunk.kvstore.status.value] + #'services/server/status/dispatch-artifacts' + splunk.server.searchartifacts.adhoc: + enabled: false + description: Gauge tracking number of ad hoc search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + unit: "{search_artifacts}" + gauge: + monotonic: false + aggregation_temporality: cumulative + value_type: int + attributes: [splunk.host] + splunk.server.searchartifacts.scheduled: + enabled: false + description: Gauge tracking number of scheduled search artifacts currently on disk. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + unit: "{search_artifacts}" + gauge: + monotonic: false + aggregation_temporality: cumulative + value_type: int + attributes: [splunk.host] + splunk.server.searchartifacts.completed: + enabled: false + description: Gauge tracking number of artifacts currently on disk that belong to finished searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + unit: "{search_artifacts}" + gauge: + monotonic: false + aggregation_temporality: cumulative + value_type: int + attributes: [splunk.host] + splunk.server.searchartifacts.incomplete: + enabled: false + description: Gauge tracking number of artifacts currently on disk that belong to unfinished/running searches. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + unit: "{search_artifacts}" + gauge: + monotonic: false + aggregation_temporality: cumulative + value_type: int + attributes: [splunk.host] + splunk.server.searchartifacts.invalid: + enabled: false + description: Gauge tracking number of artifacts currently on disk that are not in a valid state, such as missing info.csv file, etc. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + unit: "{search_artifacts}" + gauge: + monotonic: false + aggregation_temporality: cumulative + value_type: int + attributes: [splunk.host] + splunk.server.searchartifacts.savedsearches: + enabled: false + description: Gauge tracking, for the `splunk.server.searchartifacts.scheduled` number of scheduled search artifacts, how many different saved-searches they belong to. Note:* Must be pointed at specific Search Head endpoint and gathers metrics from only that Search Head. + unit: "{search_artifacts}" + gauge: + monotonic: false + aggregation_temporality: cumulative + value_type: int + attributes: [splunk.host] tests: config: diff --git a/receiver/splunkenterprisereceiver/scraper.go b/receiver/splunkenterprisereceiver/scraper.go index ed731080acad..7d55727e71e4 100644 --- a/receiver/splunkenterprisereceiver/scraper.go +++ b/receiver/splunkenterprisereceiver/scraper.go @@ -102,6 +102,7 @@ func (s *splunkScraper) scrape(ctx context.Context) (pmetric.Metrics, error) { s.scrapeSchedulerRunTimeByHost, s.scrapeIndexerAvgRate, s.scrapeKVStoreStatus, + s.scrapeSearchArtifacts, } errChan := make(chan error, len(metricScrapes)) @@ -1627,3 +1628,90 @@ func (s *splunkScraper) scrapeKVStoreStatus(ctx context.Context, now pcommon.Tim } } } + +// Scrape dispatch artifacts +func (s *splunkScraper) scrapeSearchArtifacts(ctx context.Context, now pcommon.Timestamp, errs chan error) { + if !s.splunkClient.isConfigured(typeSh) { + return + } + + ctx = context.WithValue(ctx, endpointType("type"), typeSh) + var da DispatchArtifacts + + ept := apiDict[`SplunkDispatchArtifacts`] + + req, err := s.splunkClient.createAPIRequest(ctx, ept) + if err != nil { + errs <- err + return + } + + res, err := s.splunkClient.makeRequest(req) + if err != nil { + errs <- err + return + } + defer res.Body.Close() + + body, err := io.ReadAll(res.Body) + if err != nil { + errs <- err + return + } + err = json.Unmarshal(body, &da) + if err != nil { + errs <- err + return + } + + for _, f := range da.Entries { + + if !s.conf.MetricsBuilderConfig.Metrics.SplunkServerSearchartifactsAdhoc.Enabled { + adhocCount, err := strconv.ParseInt(f.Content.AdhocCount, 10, 64) + if err != nil { + errs <- err + } + s.mb.RecordSplunkServerSearchartifactsAdhocDataPoint(now, adhocCount, s.conf.SHEndpoint.Endpoint) + } + + if !s.conf.MetricsBuilderConfig.Metrics.SplunkServerSearchartifactsScheduled.Enabled { + scheduledCount, err := strconv.ParseInt(f.Content.ScheduledCount, 10, 64) + if err != nil { + errs <- err + } + s.mb.RecordSplunkServerSearchartifactsScheduledDataPoint(now, scheduledCount, s.conf.SHEndpoint.Endpoint) + } + + if !s.conf.MetricsBuilderConfig.Metrics.SplunkServerSearchartifactsCompleted.Enabled { + completedCount, err := strconv.ParseInt(f.Content.CompletedCount, 10, 64) + if err != nil { + errs <- err + } + s.mb.RecordSplunkServerSearchartifactsCompletedDataPoint(now, completedCount, s.conf.SHEndpoint.Endpoint) + } + + if !s.conf.MetricsBuilderConfig.Metrics.SplunkServerSearchartifactsIncomplete.Enabled { + incompleCount, err := strconv.ParseInt(f.Content.IncompleCount, 10, 64) + if err != nil { + errs <- err + } + s.mb.RecordSplunkServerSearchartifactsIncompleteDataPoint(now, incompleCount, s.conf.SHEndpoint.Endpoint) + } + + if !s.conf.MetricsBuilderConfig.Metrics.SplunkServerSearchartifactsInvalid.Enabled { + invalidCount, err := strconv.ParseInt(f.Content.InvalidCount, 10, 64) + if err != nil { + errs <- err + } + s.mb.RecordSplunkServerSearchartifactsInvalidDataPoint(now, invalidCount, s.conf.SHEndpoint.Endpoint) + } + + if !s.conf.MetricsBuilderConfig.Metrics.SplunkServerSearchartifactsSavedsearches.Enabled { + savedSearchesCount, err := strconv.ParseInt(f.Content.SsCount, 10, 64) + if err != nil { + errs <- err + } + s.mb.RecordSplunkServerSearchartifactsSavedsearchesDataPoint(now, savedSearchesCount, s.conf.SHEndpoint.Endpoint) + } + } +} diff --git a/receiver/splunkenterprisereceiver/scraper_test.go b/receiver/splunkenterprisereceiver/scraper_test.go index a4a06cc84ee1..0af346d429e2 100644 --- a/receiver/splunkenterprisereceiver/scraper_test.go +++ b/receiver/splunkenterprisereceiver/scraper_test.go @@ -47,6 +47,13 @@ func mockIntrospectionQueues(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(`{"links":{},"origin":"https://somehost:8089/services/server/introspection/queues","updated":"2023-09-18T13:37:45+00:00","generator":{"build":"82c987350fde","version":"9.0.1"},"entry":[{"name":"AEQ","id":"https://somehost:8089/services/server/introspection/queues/AEQ","updated":"1970-01-01T00:00:00+00:00","links":{"alternate":"/services/server/introspection/queues/AEQ","list":"/services/server/introspection/queues/AEQ","edit":"/services/server/introspection/queues/AEQ"},"author":"system","acl":{"app":"","can_list":true,"can_write":true,"modifiable":false,"owner":"system","perms":{"read":["admin","splunk-system-role"],"write":["admin","splunk-system-role"]},"removable":false,"sharing":"system"},"content":{"cntr_1_lookback_time":60,"cntr_2_lookback_time":600,"cntr_3_lookback_time":900,"current_size":1,"current_size_bytes":100,"eai:acl":null,"largest_size":3,"max_size_bytes":512000,"sampling_interval":1,"smallest_size":0,"value_cntr1_size_bytes_lookback":0,"value_cntr1_size_lookback":0,"value_cntr2_size_bytes_lookback":0,"value_cntr2_size_lookback":0,"value_cntr3_size_bytes_lookback":0,"value_cntr3_size_lookback":0}}],"paging":{"total":13,"perPage":1,"offset":0},"messages":[]}`)) } +func mockDispatchArtifacts(w http.ResponseWriter, _ *http.Request) { + status := http.StatusOK + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + _, _ = w.Write([]byte(`{"links":{},"origin":"https://somehost:8089/services/server/status/dispatch-artifacts","updated":"2024-10-24T04:46:47+00:00","generator":{"build":"05775df3af30","version":"9.2.2406.108"},"entry":[{"name":"result","id":"https://somehost:8089/services/server/status/dispatch-artifacts/result","updated":"1970-01-01T00:00:00+00:00","links":{"alternate":"/services/server/status/dispatch-artifacts/result","list":"/services/server/status/dispatch-artifacts/result"},"author":"system","acl":{"app":"","can_list":true,"can_write":true,"modifiable":false,"owner":"system","perms":{"read":["*"],"write":[]},"removable":false,"sharing":"system"},"content":{"adhoc_count":"7","adhoc_size_mb":"1","adhoc_subsearch_count":"0","adhoc_subsearch_size_mb":"0","cached_job_status_info_csv_size_mb":"0","cached_job_status_status_csv_size_mb":"0","cached_job_status_total_entries":"20","completed_count":"20","completed_size_mb":"2","count_summary":"1","disk_usage_MB":"2","eai:acl":null,"incomple_count":"0","incomple_size_mb":"0","invalid_count":"1","remote_count":"0","remote_mb":"0","rsa_count":"0","rsa_scheduled_count":"0","rsa_scheduled_size_mb":"0","rsa_size_mb":"0","scheduled_count":"13","scheduled_size_mb":"1","scheduled_subsearch_count":"0","scheduled_subsearch_size_mb":"0","ss_count":"7","status_cache_info_csv_size_mb":"0","status_cache_status_csv_size_mb":"0","status_cache_total_entries":"20","temp_dispatch_count":"0","temp_dispatch_size_mb":"0","top_apps":{"0":{"splunk_instrumentation":"6"},"1":{"search":"1"}},"top_named_searches":null,"top_users":{"0":{"splunk-system-user":"6"},"1":{"internal_observability":"1"}},"total_count":"7"}}],"paging":{"total":1,"perPage":30,"offset":0},"messages":[]}`)) +} + // mock server create func createMockServer() *httptest.Server { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -57,6 +64,8 @@ func createMockServer() *httptest.Server { mockIndexesExtended(w, r) case "/services/server/introspection/queues?output_mode=json&count=-1": mockIntrospectionQueues(w, r) + case "/services/server/status/dispatch-artifacts?output_mode=json&count=-1": + mockDispatchArtifacts(w, r) default: http.NotFoundHandler().ServeHTTP(w, r) } diff --git a/receiver/splunkenterprisereceiver/search_result.go b/receiver/splunkenterprisereceiver/search_result.go index 2a9146411ef4..69212c4de08d 100644 --- a/receiver/splunkenterprisereceiver/search_result.go +++ b/receiver/splunkenterprisereceiver/search_result.go @@ -24,6 +24,7 @@ var apiDict = map[string]string{ `SplunkDataIndexesExtended`: `/services/data/indexes-extended?output_mode=json&count=-1`, `SplunkIntrospectionQueues`: `/services/server/introspection/queues?output_mode=json&count=-1`, `SplunkKVStoreStatus`: `/services/kvstore/status?output_mode=json`, + `SplunkDispatchArtifacts`: `/services/server/status/dispatch-artifacts?output_mode=json&count=-1`, } type searchResponse struct { @@ -134,3 +135,21 @@ type KVStoreCurrent struct { ReplicationStatus string `json:"replicationStatus"` StorageEngine string `json:"storageEngine"` } + +// '/services/server/status/dispatch-artifacts' +type DispatchArtifacts struct { + Entries []DispatchArtifactEntry `json:"entry"` +} + +type DispatchArtifactEntry struct { + Content DispatchArtifactContent `json:"content"` +} + +type DispatchArtifactContent struct { + AdhocCount string `json:"adhoc_count"` + ScheduledCount string `json:"scheduled_count"` + SsCount string `json:"ss_count"` + CompletedCount string `json:"completed_count"` + IncompleCount string `json:"incomple_count"` + InvalidCount string `json:"invalid_count"` +}