From 070d931310f5ec0d1d6f12b72999088d662224d2 Mon Sep 17 00:00:00 2001 From: Curtis Robert Date: Thu, 1 Feb 2024 16:40:33 -0800 Subject: [PATCH] [chore][receiver/sqlquery] Move reusable logic to internal package (#30709) **Description:** As noted in the related issues, a lot of the logic in the sqlquery receiver can be moved to a central package to be used by other receivers. I realize this appears to be a large change, but it's purely a re-organization PR, there's no functional changes. GitHub is not recognizing moved files, so please refer to new file names and their deleted counterparts. A lot of members are now public in the internal package that were private in the receiver which is likely what's causing GitHub to miss that they're just moved files. This doesn't require a changelog (in my mind) because all things moving were originally private to the receiver. They're now still purely internal, so they won't be published. I believe `internal` is the best destination for now as it allows us to solidify the usage and interface before moving it to `pkg` to be publicly available. There are still a lot of unknowns as far as how it can be used by other receivers, so I fully expect "breaking changes" to this. If we keep it internal we can update all usages with the changing interface, so the changes won't be breaking. **Link to tracking Issue:** #30297, #13546 --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/feature_request.yaml | 1 + .github/ISSUE_TEMPLATE/other.yaml | 1 + cmd/configschema/go.mod | 3 + cmd/otelcontribcol/builder-config.yaml | 1 + cmd/otelcontribcol/go.mod | 3 + go.mod | 3 + internal/sqlquery/Makefile | 1 + internal/sqlquery/config.go | 178 ++++++++++ internal/sqlquery/db_client.go | 93 +++++ .../sqlquery}/db_client_test.go | 57 ++-- .../sqlquery}/db_wrappers.go | 14 +- internal/sqlquery/go.mod | 111 ++++++ internal/sqlquery/go.sum | 321 ++++++++++++++++++ internal/sqlquery/metadata.yaml | 3 + .../sqlquery}/metrics.go | 4 +- .../sqlquery}/metrics_test.go | 2 +- .../sqlquery}/row_scanner.go | 6 +- internal/sqlquery/scraper.go | 107 ++++++ .../sqlquery}/scraper_test.go | 160 ++++----- receiver/sqlqueryreceiver/config.go | 167 +-------- receiver/sqlqueryreceiver/config_test.go | 73 ++-- receiver/sqlqueryreceiver/db_client.go | 77 ----- receiver/sqlqueryreceiver/factory.go | 5 +- receiver/sqlqueryreceiver/go.mod | 15 +- receiver/sqlqueryreceiver/integration_test.go | 117 +++---- receiver/sqlqueryreceiver/logs_receiver.go | 39 +-- .../sqlqueryreceiver/logs_receiver_test.go | 10 +- receiver/sqlqueryreceiver/receiver.go | 27 +- receiver/sqlqueryreceiver/receiver_test.go | 54 +-- receiver/sqlqueryreceiver/scraper.go | 89 ----- versions.yaml | 1 + 33 files changed, 1122 insertions(+), 623 deletions(-) create mode 100644 internal/sqlquery/Makefile create mode 100644 internal/sqlquery/config.go create mode 100644 internal/sqlquery/db_client.go rename {receiver/sqlqueryreceiver => internal/sqlquery}/db_client_test.go (72%) rename {receiver/sqlqueryreceiver => internal/sqlquery}/db_wrappers.go (73%) create mode 100644 internal/sqlquery/go.mod create mode 100644 internal/sqlquery/go.sum create mode 100644 internal/sqlquery/metadata.yaml rename {receiver/sqlqueryreceiver => internal/sqlquery}/metrics.go (95%) rename {receiver/sqlqueryreceiver => internal/sqlquery}/metrics_test.go (82%) rename {receiver/sqlqueryreceiver => internal/sqlquery}/row_scanner.go (88%) create mode 100644 internal/sqlquery/scraper.go rename {receiver/sqlqueryreceiver => internal/sqlquery}/scraper_test.go (83%) delete mode 100644 receiver/sqlqueryreceiver/db_client.go delete mode 100644 receiver/sqlqueryreceiver/scraper.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c57de4578db0..5395976652bd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -126,6 +126,7 @@ internal/kubelet/ @open-telemetry/collect internal/metadataproviders/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @dashpole internal/sharedcomponent/ @open-telemetry/collector-contrib-approvers @open-telemetry/collector-approvers internal/splunk/ @open-telemetry/collector-contrib-approvers @dmitryax +internal/sqlquery/ @open-telemetry/collector-contrib-approvers @crobert-1 @dmitryax internal/tools/ @open-telemetry/collector-contrib-approvers pkg/batchperresourceattr/ @open-telemetry/collector-contrib-approvers @atoulme @dmitryax diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4e9ac1cf1b89..d3c35ae45fe0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -124,6 +124,7 @@ body: - internal/metadataproviders - internal/sharedcomponent - internal/splunk + - internal/sqlquery - internal/tools - pkg/batchperresourceattr - pkg/batchpersignal diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index e2120c8364f2..e8b8e3016828 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -118,6 +118,7 @@ body: - internal/metadataproviders - internal/sharedcomponent - internal/splunk + - internal/sqlquery - internal/tools - pkg/batchperresourceattr - pkg/batchpersignal diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index 09c9202dc031..cf03cb515b3e 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -118,6 +118,7 @@ body: - internal/metadataproviders - internal/sharedcomponent - internal/splunk + - internal/sqlquery - internal/tools - pkg/batchperresourceattr - pkg/batchpersignal diff --git a/cmd/configschema/go.mod b/cmd/configschema/go.mod index 7cb9641de4aa..569248d75ca8 100644 --- a/cmd/configschema/go.mod +++ b/cmd/configschema/go.mod @@ -77,6 +77,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/internal/kubelet v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.93.0 // indirect @@ -1150,3 +1151,5 @@ replace ( github.com/open-telemetry/opentelemetry-collector-contrib/connector/servicegraphconnector => ../../connector/servicegraphconnector github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector => ../../connector/spanmetricsconnector ) + +replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery => ../../internal/sqlquery diff --git a/cmd/otelcontribcol/builder-config.yaml b/cmd/otelcontribcol/builder-config.yaml index 146195c85780..dcbb93e1385a 100644 --- a/cmd/otelcontribcol/builder-config.yaml +++ b/cmd/otelcontribcol/builder-config.yaml @@ -453,3 +453,4 @@ replaces: - github.com/open-telemetry/opentelemetry-collector-contrib/extension/opampextension => ../../extension/opampextension - github.com/open-telemetry/opentelemetry-collector-contrib/extension/solarwindsapmsettingsextension => ../../extension/solarwindsapmsettingsextension - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/namedpipereceiver => ../../receiver/namedpipereceiver + - github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery => ../../internal/sqlquery diff --git a/cmd/otelcontribcol/go.mod b/cmd/otelcontribcol/go.mod index a5402c45e964..485897d16b08 100644 --- a/cmd/otelcontribcol/go.mod +++ b/cmd/otelcontribcol/go.mod @@ -547,6 +547,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata v0.93.0 // indirect @@ -1191,3 +1192,5 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/extension/opam replace github.com/open-telemetry/opentelemetry-collector-contrib/extension/solarwindsapmsettingsextension => ../../extension/solarwindsapmsettingsextension replace github.com/open-telemetry/opentelemetry-collector-contrib/receiver/namedpipereceiver => ../../receiver/namedpipereceiver + +replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery => ../../internal/sqlquery diff --git a/go.mod b/go.mod index a4d385e68fdc..d59e68002fcc 100644 --- a/go.mod +++ b/go.mod @@ -516,6 +516,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.93.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata v0.93.0 // indirect @@ -1151,3 +1152,5 @@ replace ( github.com/open-telemetry/opentelemetry-collector-contrib/connector/servicegraphconnector => ./connector/servicegraphconnector github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector => ./connector/spanmetricsconnector ) + +replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery => ./internal/sqlquery diff --git a/internal/sqlquery/Makefile b/internal/sqlquery/Makefile new file mode 100644 index 000000000000..ded7a36092dc --- /dev/null +++ b/internal/sqlquery/Makefile @@ -0,0 +1 @@ +include ../../Makefile.Common diff --git a/internal/sqlquery/config.go b/internal/sqlquery/config.go new file mode 100644 index 000000000000..d45fbf4a9960 --- /dev/null +++ b/internal/sqlquery/config.go @@ -0,0 +1,178 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" + +import ( + "errors" + "fmt" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/receiver/scraperhelper" + "go.uber.org/multierr" +) + +type Config struct { + scraperhelper.ScraperControllerSettings `mapstructure:",squash"` + Driver string `mapstructure:"driver"` + DataSource string `mapstructure:"datasource"` + Queries []Query `mapstructure:"queries"` + StorageID *component.ID `mapstructure:"storage"` + Telemetry TelemetryConfig `mapstructure:"telemetry"` +} + +func (c Config) Validate() error { + if c.Driver == "" { + return errors.New("'driver' cannot be empty") + } + if c.DataSource == "" { + return errors.New("'datasource' cannot be empty") + } + if len(c.Queries) == 0 { + return errors.New("'queries' cannot be empty") + } + for _, query := range c.Queries { + if err := query.Validate(); err != nil { + return err + } + } + return nil +} + +type Query struct { + SQL string `mapstructure:"sql"` + Metrics []MetricCfg `mapstructure:"metrics"` + Logs []LogsCfg `mapstructure:"logs"` + TrackingColumn string `mapstructure:"tracking_column"` + TrackingStartValue string `mapstructure:"tracking_start_value"` +} + +func (q Query) Validate() error { + var errs error + if q.SQL == "" { + errs = multierr.Append(errs, errors.New("'query.sql' cannot be empty")) + } + if len(q.Logs) == 0 && len(q.Metrics) == 0 { + errs = multierr.Append(errs, errors.New("at least one of 'query.logs' and 'query.metrics' must not be empty")) + } + for _, logs := range q.Logs { + if err := logs.Validate(); err != nil { + errs = multierr.Append(errs, err) + } + } + for _, metric := range q.Metrics { + if err := metric.Validate(); err != nil { + errs = multierr.Append(errs, err) + } + } + return errs +} + +type LogsCfg struct { + BodyColumn string `mapstructure:"body_column"` +} + +func (config LogsCfg) Validate() error { + var errs error + if config.BodyColumn == "" { + errs = multierr.Append(errs, errors.New("'body_column' must not be empty")) + } + return errs +} + +type MetricCfg struct { + MetricName string `mapstructure:"metric_name"` + ValueColumn string `mapstructure:"value_column"` + AttributeColumns []string `mapstructure:"attribute_columns"` + Monotonic bool `mapstructure:"monotonic"` + ValueType MetricValueType `mapstructure:"value_type"` + DataType MetricType `mapstructure:"data_type"` + Aggregation MetricAggregation `mapstructure:"aggregation"` + Unit string `mapstructure:"unit"` + Description string `mapstructure:"description"` + StaticAttributes map[string]string `mapstructure:"static_attributes"` + StartTsColumn string `mapstructure:"start_ts_column"` + TsColumn string `mapstructure:"ts_column"` +} + +func (c MetricCfg) Validate() error { + var errs error + if c.MetricName == "" { + errs = multierr.Append(errs, errors.New("'metric_name' cannot be empty")) + } + if c.ValueColumn == "" { + errs = multierr.Append(errs, errors.New("'value_column' cannot be empty")) + } + if err := c.ValueType.Validate(); err != nil { + errs = multierr.Append(errs, err) + } + if err := c.DataType.Validate(); err != nil { + errs = multierr.Append(errs, err) + } + if err := c.Aggregation.Validate(); err != nil { + errs = multierr.Append(errs, err) + } + if c.DataType == MetricTypeGauge && c.Aggregation != "" { + errs = multierr.Append(errs, fmt.Errorf("aggregation=%s but data_type=%s does not support aggregation", c.Aggregation, c.DataType)) + } + if errs != nil && c.MetricName != "" { + errs = multierr.Append(fmt.Errorf("invalid metric config with metric_name '%s'", c.MetricName), errs) + } + return errs +} + +type MetricType string + +const ( + MetricTypeUnspecified MetricType = "" + MetricTypeGauge MetricType = "gauge" + MetricTypeSum MetricType = "sum" +) + +func (t MetricType) Validate() error { + switch t { + case MetricTypeUnspecified, MetricTypeGauge, MetricTypeSum: + return nil + } + return fmt.Errorf("metric config has unsupported data_type: '%s'", t) +} + +type MetricValueType string + +const ( + MetricValueTypeUnspecified MetricValueType = "" + MetricValueTypeInt MetricValueType = "int" + MetricValueTypeDouble MetricValueType = "double" +) + +func (t MetricValueType) Validate() error { + switch t { + case MetricValueTypeUnspecified, MetricValueTypeInt, MetricValueTypeDouble: + return nil + } + return fmt.Errorf("metric config has unsupported value_type: '%s'", t) +} + +type MetricAggregation string + +const ( + MetricAggregationUnspecified MetricAggregation = "" + MetricAggregationCumulative MetricAggregation = "cumulative" + MetricAggregationDelta MetricAggregation = "delta" +) + +func (a MetricAggregation) Validate() error { + switch a { + case MetricAggregationUnspecified, MetricAggregationCumulative, MetricAggregationDelta: + return nil + } + return fmt.Errorf("metric config has unsupported aggregation: '%s'", a) +} + +type TelemetryConfig struct { + Logs TelemetryLogsConfig `mapstructure:"logs"` +} + +type TelemetryLogsConfig struct { + Query bool `mapstructure:"query"` +} diff --git a/internal/sqlquery/db_client.go b/internal/sqlquery/db_client.go new file mode 100644 index 000000000000..9f7d00908f0f --- /dev/null +++ b/internal/sqlquery/db_client.go @@ -0,0 +1,93 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" + +import ( + "context" + + // register Db drivers + _ "github.com/SAP/go-hdb/driver" + _ "github.com/go-sql-driver/mysql" + _ "github.com/lib/pq" + _ "github.com/microsoft/go-mssqldb" + _ "github.com/microsoft/go-mssqldb/integratedauth/krb5" + _ "github.com/sijms/go-ora/v2" + _ "github.com/snowflakedb/gosnowflake" + "go.uber.org/multierr" + "go.uber.org/zap" +) + +type StringMap map[string]string + +type DbClient interface { + QueryRows(ctx context.Context, args ...any) ([]StringMap, error) +} + +type DbSQLClient struct { + Db Db + Logger *zap.Logger + Telemetry TelemetryConfig + SQL string +} + +func NewDbClient(db Db, sql string, logger *zap.Logger, telemetry TelemetryConfig) DbClient { + return DbSQLClient{ + Db: db, + SQL: sql, + Logger: logger, + Telemetry: telemetry, + } +} + +func (cl DbSQLClient) QueryRows(ctx context.Context, args ...any) ([]StringMap, error) { + cl.Logger.Debug("Running query", cl.prepareQueryFields(cl.SQL, args)...) + sqlRows, err := cl.Db.QueryContext(ctx, cl.SQL, args...) + if err != nil { + return nil, err + } + var out []StringMap + colTypes, err := sqlRows.ColumnTypes() + if err != nil { + return nil, err + } + scanner := newRowScanner(colTypes) + var warnings error + for sqlRows.Next() { + err = scanner.scan(sqlRows) + if err != nil { + return nil, err + } + sm, scanErr := scanner.toStringMap() + if scanErr != nil { + warnings = multierr.Append(warnings, scanErr) + } + out = append(out, sm) + } + return out, warnings +} + +func (cl DbSQLClient) prepareQueryFields(sql string, args []any) []zap.Field { + var logFields []zap.Field + if cl.Telemetry.Logs.Query { + logFields = append(logFields, zap.String("query", sql)) + logFields = append(logFields, zap.Any("parameters", args)) + } + return logFields +} + +// This is only used for testing, but need to be exposed to other packages. +type FakeDBClient struct { + RequestCounter int + StringMaps [][]StringMap + Err error +} + +func (c *FakeDBClient) QueryRows(context.Context, ...any) ([]StringMap, error) { + if c.Err != nil { + return nil, c.Err + } + idx := c.RequestCounter + c.RequestCounter++ + return c.StringMaps[idx], nil +} diff --git a/receiver/sqlqueryreceiver/db_client_test.go b/internal/sqlquery/db_client_test.go similarity index 72% rename from receiver/sqlqueryreceiver/db_client_test.go rename to internal/sqlquery/db_client_test.go index 4fb591c68be4..a40ebd02e31f 100644 --- a/receiver/sqlqueryreceiver/db_client_test.go +++ b/internal/sqlquery/db_client_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package sqlqueryreceiver +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" import ( "context" @@ -16,12 +16,12 @@ import ( ) func TestDBSQLClient_SingleRow(t *testing.T) { - cl := dbSQLClient{ - db: fakeDB{rowVals: [][]any{{42, 123.4, "hello", true, []uint8{52, 46, 49}}}}, - logger: zap.NewNop(), - sql: "", + cl := DbSQLClient{ + Db: fakeDB{rowVals: [][]any{{42, 123.4, "hello", true, []uint8{52, 46, 49}}}}, + Logger: zap.NewNop(), + SQL: "", } - rows, err := cl.queryRows(context.Background()) + rows, err := cl.QueryRows(context.Background()) require.NoError(t, err) assert.Len(t, rows, 1) assert.EqualValues(t, map[string]string{ @@ -34,15 +34,15 @@ func TestDBSQLClient_SingleRow(t *testing.T) { } func TestDBSQLClient_MultiRow(t *testing.T) { - cl := dbSQLClient{ - db: fakeDB{rowVals: [][]any{ + cl := DbSQLClient{ + Db: fakeDB{rowVals: [][]any{ {42, 123.4, "hello", true, []uint8{52, 46, 49}}, {43, 123.5, "goodbye", false, []uint8{52, 46, 50}}, }}, - logger: zap.NewNop(), - sql: "", + Logger: zap.NewNop(), + SQL: "", } - rows, err := cl.queryRows(context.Background()) + rows, err := cl.QueryRows(context.Background()) require.NoError(t, err) assert.Len(t, rows, 2) assert.EqualValues(t, map[string]string{ @@ -62,14 +62,14 @@ func TestDBSQLClient_MultiRow(t *testing.T) { } func TestDBSQLClient_Nulls(t *testing.T) { - cl := dbSQLClient{ - db: fakeDB{rowVals: [][]any{ + cl := DbSQLClient{ + Db: fakeDB{rowVals: [][]any{ {42, nil, 111}, // NULLs from the DB map to nil here }}, - logger: zap.NewNop(), - sql: "", + Logger: zap.NewNop(), + SQL: "", } - rows, err := cl.queryRows(context.Background()) + rows, err := cl.QueryRows(context.Background()) assert.Error(t, err) assert.True(t, errors.Is(err, errNullValueWarning)) assert.Len(t, rows, 1) @@ -80,15 +80,15 @@ func TestDBSQLClient_Nulls(t *testing.T) { } func TestDBSQLClient_Nulls_MultiRow(t *testing.T) { - cl := dbSQLClient{ - db: fakeDB{rowVals: [][]any{ + cl := DbSQLClient{ + Db: fakeDB{rowVals: [][]any{ {42, nil}, {43, nil}, }}, - logger: zap.NewNop(), - sql: "", + Logger: zap.NewNop(), + SQL: "", } - rows, err := cl.queryRows(context.Background()) + rows, err := cl.QueryRows(context.Background()) assert.Error(t, err) errs := multierr.Errors(err) for _, err := range errs { @@ -145,18 +145,3 @@ type fakeCol struct { func (c fakeCol) Name() string { return c.name } - -type fakeDBClient struct { - requestCounter int - stringMaps [][]stringMap - err error -} - -func (c *fakeDBClient) queryRows(context.Context, ...any) ([]stringMap, error) { - if c.err != nil { - return nil, c.err - } - idx := c.requestCounter - c.requestCounter++ - return c.stringMaps[idx], nil -} diff --git a/receiver/sqlqueryreceiver/db_wrappers.go b/internal/sqlquery/db_wrappers.go similarity index 73% rename from receiver/sqlqueryreceiver/db_wrappers.go rename to internal/sqlquery/db_wrappers.go index 5c8d88073afd..a8b788c82dd8 100644 --- a/receiver/sqlqueryreceiver/db_wrappers.go +++ b/internal/sqlquery/db_wrappers.go @@ -1,16 +1,16 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package sqlqueryreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver" +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" import ( "context" "database/sql" ) -// These are wrappers and interfaces around sql.DB so that it can be swapped out for testing. +// These are wrappers and interfaces around SQL.DB so that it can be swapped out for testing. -type db interface { +type Db interface { QueryContext(ctx context.Context, query string, args ...any) (rows, error) } @@ -24,12 +24,12 @@ type colType interface { Name() string } -type dbWrapper struct { - db *sql.DB +type DbWrapper struct { + Db *sql.DB } -func (d dbWrapper) QueryContext(ctx context.Context, query string, args ...any) (rows, error) { - rows, err := d.db.QueryContext(ctx, query, args...) +func (d DbWrapper) QueryContext(ctx context.Context, query string, args ...any) (rows, error) { + rows, err := d.Db.QueryContext(ctx, query, args...) return rowsWrapper{rows}, err } diff --git a/internal/sqlquery/go.mod b/internal/sqlquery/go.mod new file mode 100644 index 000000000000..6f6f9b313482 --- /dev/null +++ b/internal/sqlquery/go.mod @@ -0,0 +1,111 @@ +module github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery + +go 1.20 + +require ( + github.com/SAP/go-hdb v1.7.7 + github.com/go-sql-driver/mysql v1.7.1 + github.com/lib/pq v1.10.9 + github.com/microsoft/go-mssqldb v1.6.0 + github.com/sijms/go-ora/v2 v2.8.6 + github.com/snowflakedb/gosnowflake v1.7.2 + github.com/stretchr/testify v1.8.4 + go.opentelemetry.io/collector/component v0.93.1-0.20240130182548-89388addcc7f + go.opentelemetry.io/collector/pdata v1.0.2-0.20240130181942-9c7177496fd5 + go.opentelemetry.io/collector/receiver v0.93.1-0.20240130182548-89388addcc7f + go.uber.org/multierr v1.11.0 + go.uber.org/zap v1.26.0 +) + +require ( + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 // indirect + github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect + github.com/apache/arrow/go/v14 v14.0.2 // indirect + github.com/aws/aws-sdk-go-v2 v1.17.7 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.18 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.59 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.31 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.23 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.26 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.25 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.0 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.31.0 // indirect + github.com/aws/smithy-go v1.13.5 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dvsekhvalnov/jose2go v1.6.0 // indirect + github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/flatbuffers v23.5.26+incompatible // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/goidentity/v6 v6.0.1 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/knadh/koanf/maps v0.1.1 // indirect + github.com/knadh/koanf/providers/confmap v0.1.0 // indirect + github.com/knadh/koanf/v2 v2.0.1 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/pierrec/lz4/v4 v4.1.18 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.46.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/zeebo/xxh3 v1.0.2 // indirect + go.opentelemetry.io/collector v0.93.1-0.20240130182548-89388addcc7f // indirect + go.opentelemetry.io/collector/config/configtelemetry v0.93.1-0.20240130182548-89388addcc7f // indirect + go.opentelemetry.io/collector/confmap v0.93.1-0.20240130182548-89388addcc7f // indirect + go.opentelemetry.io/collector/consumer v0.93.1-0.20240130182548-89388addcc7f // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.45.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/sdk v1.22.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.17.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/grpc v1.61.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/internal/sqlquery/go.sum b/internal/sqlquery/go.sum new file mode 100644 index 000000000000..554cdd09e397 --- /dev/null +++ b/internal/sqlquery/go.sum @@ -0,0 +1,321 @@ +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/SAP/go-hdb v1.7.7 h1:yA/KE5ozzHfPrPlOf7yAPUwbFGrJXBcdnBkQwUKG/VE= +github.com/SAP/go-hdb v1.7.7/go.mod h1:P56UwOZO7QpDS0wyEWFPSxtyjwwbFBs3eFuOU/TSCvk= +github.com/apache/arrow/go/v14 v14.0.2 h1:N8OkaJEOfI3mEZt07BIkvo4sC6XDbL+48MBPWO5IONw= +github.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY= +github.com/aws/aws-sdk-go-v2 v1.17.7 h1:CLSjnhJSTSogvqUGhIC6LqFKATMRexcxLZ0i/Nzk9Eg= +github.com/aws/aws-sdk-go-v2 v1.17.7/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= +github.com/aws/aws-sdk-go-v2/config v1.18.19 h1:AqFK6zFNtq4i1EYu+eC7lcKHYnZagMn6SW171la0bGw= +github.com/aws/aws-sdk-go-v2/config v1.18.19/go.mod h1:XvTmGMY8d52ougvakOv1RpiTLPz9dlG/OQHsKU/cMmY= +github.com/aws/aws-sdk-go-v2/credentials v1.13.18 h1:EQMdtHwz0ILTW1hoP+EwuWhwCG1hD6l3+RWFQABET4c= +github.com/aws/aws-sdk-go-v2/credentials v1.13.18/go.mod h1:vnwlwjIe+3XJPBYKu1et30ZPABG3VaXJYr8ryohpIyM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.1 h1:gt57MN3liKiyGopcqgNzJb2+d9MJaKT/q1OksHNXVE4= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.1/go.mod h1:lfUx8puBRdM5lVVMQlwt2v+ofiG/X6Ms+dy0UkG/kXw= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.59 h1:E3Y+OfzOK1+rmRo/K2G0ml8Vs+Xqk0kOnf4nS0kUtBc= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.59/go.mod h1:1M4PLSBUVfBI0aP+C9XI7SM6kZPCGYyI6izWz0TGprE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.31 h1:sJLYcS+eZn5EeNINGHSCRAwUJMFVqklwkH36Vbyai7M= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.31/go.mod h1:QT0BqUvX1Bh2ABdTGnjqEjvjzrCfIniM9Sc8zn9Yndo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.25 h1:1mnRASEKnkqsntcxHaysxwgVoUUp5dkiB+l3llKnqyg= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.25/go.mod h1:zBHOPwhBc3FlQjQJE/D3IfPWiWaQmT06Vq9aNukDo0k= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.32 h1:p5luUImdIqywn6JpQsW3tq5GNOxKmOnEpybzPx+d1lk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.32/go.mod h1:XGhIBZDEgfqmFIugclZ6FU7v75nHhBDtzuB4xB/tEi4= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.23 h1:DWYZIsyqagnWL00f8M/SOr9fN063OEQWn9LLTbdYXsk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.23/go.mod h1:uIiFgURZbACBEQJfqTZPb/jxO7R+9LeoHUFudtIdeQI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.26 h1:CeuSeq/8FnYpPtnuIeLQEEvDv9zUjneuYi8EghMBdwQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.26/go.mod h1:2UqAAwMUXKeRkAHIlDJqvMVgOWkUi/AUXPk/YIe+Dg4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.25 h1:5LHn8JQ0qvjD9L9JhMtylnkcw7j05GDZqM9Oin6hpr0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.25/go.mod h1:/95IA+0lMnzW6XzqYJRpjjsAbKEORVeO0anQqjd2CNU= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.0 h1:e2ooMhpYGhDnBfSvIyusvAwX7KexuZaHbQY2Dyei7VU= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.0/go.mod h1:bh2E0CXKZsQN+faiKVqC40vfNMAWheoULBCnEgO9K+8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.31.0 h1:B1G2pSPvbAtQjilPq+Y7jLIzCOwKzuVEl+aBBaNG0AQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.31.0/go.mod h1:ncltU6n4Nof5uJttDtcNQ537uNuwYqsZZQcpkd2/GUQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.6 h1:5V7DWLBd7wTELVz5bPpwzYy/sikk0gsgZfj40X+l5OI= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.6/go.mod h1:Y1VOmit/Fn6Tz1uFAeCO6Q7M2fmfXSCLeL5INVYsLuY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.6 h1:B8cauxOH1W1v7rd8RdI/MWnoR4Ze0wIHWrb90qczxj4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.6/go.mod h1:Lh/bc9XUf8CfOY6Jp5aIkQtN+j1mc+nExc+KXj9jx2s= +github.com/aws/aws-sdk-go-v2/service/sts v1.18.7 h1:bWNgNdRko2x6gqa0blfATqAZKZokPIeM1vfmQt2pnvM= +github.com/aws/aws-sdk-go-v2/service/sts v1.18.7/go.mod h1:JuTnSoeePXmMVe9G8NcjjwgOKEfZ4cOjMuT2IBT/2eI= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= +github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8= +github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= +github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs= +github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= +github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= +github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= +github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g= +github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= +github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= +github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= +github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/sijms/go-ora/v2 v2.8.6 h1:sq907Z5cno0YIXidOYM85tiQFFVhhgssw09IJPG0WG4= +github.com/sijms/go-ora/v2 v2.8.6/go.mod h1:EHxlY6x7y9HAsdfumurRfTd+v8NrEOTR3Xl4FWlH6xk= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/snowflakedb/gosnowflake v1.7.2 h1:HRSwva8YXC64WUppfmHcMNVVzSE1+EwXXaJxgS0EkTo= +github.com/snowflakedb/gosnowflake v1.7.2/go.mod h1:03tW856vc3ceM4rJuj7KO4dzqN7qoezTm+xw7aPIIFo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.opentelemetry.io/collector v0.93.1-0.20240130182548-89388addcc7f h1:NgQcLNPP/6YnIfNUkDkKu1uiRTXUa9kMtfpsKSVC4dY= +go.opentelemetry.io/collector v0.93.1-0.20240130182548-89388addcc7f/go.mod h1:rEqeAsOy8Mu6HA6oMjGk7NrTb7958XmShSaapxFEeTs= +go.opentelemetry.io/collector/component v0.93.1-0.20240130182548-89388addcc7f h1:DNFOx9vwV7g+lWz9htP/Biiwwp+oFifR+J2zKnQKV3U= +go.opentelemetry.io/collector/component v0.93.1-0.20240130182548-89388addcc7f/go.mod h1:jOHaBlhWt4aarDS6w9A9GcgGCxrtEg+8LnBK7Y/6zqo= +go.opentelemetry.io/collector/config/configtelemetry v0.93.1-0.20240130182548-89388addcc7f h1:S1mp1jVnxg0tyy7uFEMHDFRqI4AiqqE/ia8RPj3SKW0= +go.opentelemetry.io/collector/config/configtelemetry v0.93.1-0.20240130182548-89388addcc7f/go.mod h1:2XLhyR/GVpWeZ2K044vCmrvH/d4Ewt0aD/y46avZyMU= +go.opentelemetry.io/collector/confmap v0.93.1-0.20240130182548-89388addcc7f h1:HIvqzK7ANxcVRhtJ/zUm+ZWGHlGo7TClqcaNMwQgzHs= +go.opentelemetry.io/collector/confmap v0.93.1-0.20240130182548-89388addcc7f/go.mod h1:KjHrfxKKojaLDc9zDPfVuyp8765AH+XfcoPWMLMiuHU= +go.opentelemetry.io/collector/consumer v0.93.1-0.20240130182548-89388addcc7f h1:xtOtkpXNP7x+CmP5hpIVNOkfPUQQbWlsjSNUUlczfrE= +go.opentelemetry.io/collector/consumer v0.93.1-0.20240130182548-89388addcc7f/go.mod h1:RhC4X/bSMIENk68hzFS9i6I7DVsZSfF/S7JvfaqZkkI= +go.opentelemetry.io/collector/pdata v1.0.2-0.20240130181942-9c7177496fd5 h1:cMc7sJ29OzK5jZqr6XFzKxiJvlypR/zt2TDhPDqpBic= +go.opentelemetry.io/collector/pdata v1.0.2-0.20240130181942-9c7177496fd5/go.mod h1:IDkDj+B4Fp4wWOclBELN97zcb98HugJ8Q2gA4ZFsN8Q= +go.opentelemetry.io/collector/receiver v0.93.1-0.20240130182548-89388addcc7f h1:2C2QYMLF6YrRJPT/9LhRmfJ0wwF8nt4LjBblBCEJZtM= +go.opentelemetry.io/collector/receiver v0.93.1-0.20240130182548-89388addcc7f/go.mod h1:bPAxjHDsXFJZKPAturS7Ar5DDY/HJz5sj73E72vSVqk= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/exporters/prometheus v0.45.0 h1:BeIK2KGho0oCWa7LxEGSqfDZbs7Fpv/Viz+FS4P8CXE= +go.opentelemetry.io/otel/exporters/prometheus v0.45.0/go.mod h1:UVJZPLnfDSvHj+eJuZE+E1GjIBD267mEMfAAHJdghWg= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= +go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel/sdk/metric v1.22.0 h1:ARrRetm1HCVxq0cbnaZQlfwODYJHo3gFL8Z3tSmHBcI= +go.opentelemetry.io/otel/sdk/metric v1.22.0/go.mod h1:KjQGeMIDlBNEOo6HvjhxIec1p/69/kULDcp4gr0oLQQ= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA= +golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/sqlquery/metadata.yaml b/internal/sqlquery/metadata.yaml new file mode 100644 index 000000000000..eab1270e4726 --- /dev/null +++ b/internal/sqlquery/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [crobert-1, dmitryax] diff --git a/receiver/sqlqueryreceiver/metrics.go b/internal/sqlquery/metrics.go similarity index 95% rename from receiver/sqlqueryreceiver/metrics.go rename to internal/sqlquery/metrics.go index 52799c67bdb7..4a00e3b6269d 100644 --- a/receiver/sqlqueryreceiver/metrics.go +++ b/internal/sqlquery/metrics.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package sqlqueryreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver" +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" import ( "fmt" @@ -12,7 +12,7 @@ import ( "go.opentelemetry.io/collector/receiver/scraperhelper" ) -func rowToMetric(row stringMap, cfg MetricCfg, dest pmetric.Metric, startTime pcommon.Timestamp, ts pcommon.Timestamp, scrapeCfg scraperhelper.ScraperControllerSettings) error { +func rowToMetric(row StringMap, cfg MetricCfg, dest pmetric.Metric, startTime pcommon.Timestamp, ts pcommon.Timestamp, scrapeCfg scraperhelper.ScraperControllerSettings) error { dest.SetName(cfg.MetricName) dest.SetDescription(cfg.Description) dest.SetUnit(cfg.Unit) diff --git a/receiver/sqlqueryreceiver/metrics_test.go b/internal/sqlquery/metrics_test.go similarity index 82% rename from receiver/sqlqueryreceiver/metrics_test.go rename to internal/sqlquery/metrics_test.go index 2af66008a435..d5d46746a9ea 100644 --- a/receiver/sqlqueryreceiver/metrics_test.go +++ b/internal/sqlquery/metrics_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package sqlqueryreceiver +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" import ( "testing" diff --git a/receiver/sqlqueryreceiver/row_scanner.go b/internal/sqlquery/row_scanner.go similarity index 88% rename from receiver/sqlqueryreceiver/row_scanner.go rename to internal/sqlquery/row_scanner.go index 99c71ac0299a..9ed0711dc97e 100644 --- a/receiver/sqlqueryreceiver/row_scanner.go +++ b/internal/sqlquery/row_scanner.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package sqlqueryreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver" +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" import ( "errors" @@ -52,8 +52,8 @@ func (rs *rowScanner) scan(sqlRows rows) error { return sqlRows.Scan(rs.scanTarget...) } -func (rs *rowScanner) toStringMap() (stringMap, error) { - out := stringMap{} +func (rs *rowScanner) toStringMap() (StringMap, error) { + out := StringMap{} var errs error for k, f := range rs.cols { s, err := f() diff --git a/internal/sqlquery/scraper.go b/internal/sqlquery/scraper.go new file mode 100644 index 000000000000..e43edf4aea34 --- /dev/null +++ b/internal/sqlquery/scraper.go @@ -0,0 +1,107 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" + +import ( + "context" + "database/sql" + "errors" + "fmt" + "time" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver/scrapererror" + "go.opentelemetry.io/collector/receiver/scraperhelper" + "go.uber.org/multierr" + "go.uber.org/zap" +) + +type SQLOpenerFunc func(driverName, dataSourceName string) (*sql.DB, error) + +type DbProviderFunc func() (*sql.DB, error) + +type ClientProviderFunc func(Db, string, *zap.Logger, TelemetryConfig) DbClient + +type Scraper struct { + id component.ID + Query Query + ScrapeCfg scraperhelper.ScraperControllerSettings + StartTime pcommon.Timestamp + ClientProviderFunc ClientProviderFunc + DbProviderFunc DbProviderFunc + Logger *zap.Logger + Telemetry TelemetryConfig + Client DbClient + Db *sql.DB +} + +var _ scraperhelper.Scraper = (*Scraper)(nil) + +func NewScraper(id component.ID, query Query, scrapeCfg scraperhelper.ScraperControllerSettings, logger *zap.Logger, telemetry TelemetryConfig, dbProviderFunc DbProviderFunc, clientProviderFunc ClientProviderFunc) *Scraper { + return &Scraper{ + id: id, + Query: query, + ScrapeCfg: scrapeCfg, + Logger: logger, + Telemetry: telemetry, + DbProviderFunc: dbProviderFunc, + ClientProviderFunc: clientProviderFunc, + } +} + +func (s *Scraper) ID() component.ID { + return s.id +} + +func (s *Scraper) Start(context.Context, component.Host) error { + var err error + s.Db, err = s.DbProviderFunc() + if err != nil { + return fmt.Errorf("failed to open Db connection: %w", err) + } + s.Client = s.ClientProviderFunc(DbWrapper{s.Db}, s.Query.SQL, s.Logger, s.Telemetry) + s.StartTime = pcommon.NewTimestampFromTime(time.Now()) + + return nil +} + +func (s *Scraper) Scrape(ctx context.Context) (pmetric.Metrics, error) { + out := pmetric.NewMetrics() + rows, err := s.Client.QueryRows(ctx) + if err != nil { + if errors.Is(err, errNullValueWarning) { + s.Logger.Warn("problems encountered getting metric rows", zap.Error(err)) + } else { + return out, fmt.Errorf("Scraper: %w", err) + } + } + ts := pcommon.NewTimestampFromTime(time.Now()) + rms := out.ResourceMetrics() + rm := rms.AppendEmpty() + sms := rm.ScopeMetrics() + sm := sms.AppendEmpty() + ms := sm.Metrics() + var errs error + for _, metricCfg := range s.Query.Metrics { + for i, row := range rows { + if err = rowToMetric(row, metricCfg, ms.AppendEmpty(), s.StartTime, ts, s.ScrapeCfg); err != nil { + err = fmt.Errorf("row %d: %w", i, err) + errs = multierr.Append(errs, err) + } + } + } + if errs != nil { + return out, scrapererror.NewPartialScrapeError(errs, len(multierr.Errors(errs))) + } + return out, nil +} + +func (s *Scraper) Shutdown(_ context.Context) error { + if s.Db != nil { + return s.Db.Close() + } + return nil +} diff --git a/receiver/sqlqueryreceiver/scraper_test.go b/internal/sqlquery/scraper_test.go similarity index 83% rename from receiver/sqlqueryreceiver/scraper_test.go rename to internal/sqlquery/scraper_test.go index fc43e545b7e4..e4567a189459 100644 --- a/receiver/sqlqueryreceiver/scraper_test.go +++ b/internal/sqlquery/scraper_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package sqlqueryreceiver +package sqlquery // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" import ( "context" @@ -19,8 +19,8 @@ import ( ) func TestScraper_ErrorOnStart(t *testing.T) { - scrpr := scraper{ - dbProviderFunc: func() (*sql.DB, error) { + scrpr := Scraper{ + DbProviderFunc: func() (*sql.DB, error) { return nil, errors.New("oops") }, } @@ -29,25 +29,25 @@ func TestScraper_ErrorOnStart(t *testing.T) { } func TestScraper_ClientErrorOnScrape(t *testing.T) { - client := &fakeDBClient{ - err: errors.New("oops"), + client := &FakeDBClient{ + Err: errors.New("oops"), } - scrpr := scraper{ - client: client, + scrpr := Scraper{ + Client: client, } _, err := scrpr.Scrape(context.Background()) require.Error(t, err) } func TestScraper_RowToMetricErrorOnScrape_Float(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{ {{"myfloat": "blah"}}, }, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.float", ValueColumn: "myfloat", @@ -62,14 +62,14 @@ func TestScraper_RowToMetricErrorOnScrape_Float(t *testing.T) { } func TestScraper_RowToMetricErrorOnScrape_Int(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{ {{"myint": "blah"}}, }, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.int", ValueColumn: "myint", @@ -84,15 +84,15 @@ func TestScraper_RowToMetricErrorOnScrape_Int(t *testing.T) { } func TestScraper_RowToMetricMultiErrorsOnScrape(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{{ {"myint": "foo"}, {"myint": "bar"}, }}, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.col", ValueColumn: "mycol", @@ -107,15 +107,15 @@ func TestScraper_RowToMetricMultiErrorsOnScrape(t *testing.T) { } func TestScraper_SingleRow_MultiMetrics(t *testing.T) { - scrpr := scraper{ - client: &fakeDBClient{ - stringMaps: [][]stringMap{{{ + scrpr := Scraper{ + Client: &FakeDBClient{ + StringMaps: [][]StringMap{{{ "count": "42", "foo_name": "baz", "bar_name": "quux", }}}, }, - query: Query{ + Query: Query{ Metrics: []MetricCfg{ { MetricName: "my.metric.1", @@ -178,8 +178,8 @@ func TestScraper_SingleRow_MultiMetrics(t *testing.T) { } func TestScraper_MultiRow(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{{ { "count": "42", "genre": "action", @@ -190,9 +190,9 @@ func TestScraper_MultiRow(t *testing.T) { }, }}, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{ { MetricName: "movie.genre", @@ -224,15 +224,15 @@ func TestScraper_MultiRow(t *testing.T) { } func TestScraper_MultiResults_CumulativeSum(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{ {{"count": "42"}}, {{"count": "43"}}, }, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "transaction.count", ValueColumn: "count", @@ -247,15 +247,15 @@ func TestScraper_MultiResults_CumulativeSum(t *testing.T) { } func TestScraper_MultiResults_DeltaSum(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{ {{"count": "42"}}, {{"count": "43"}}, }, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "transaction.count", ValueColumn: "count", @@ -269,7 +269,7 @@ func TestScraper_MultiResults_DeltaSum(t *testing.T) { assertTransactionCount(t, scrpr, 43, pmetric.AggregationTemporalityDelta) } -func assertTransactionCount(t *testing.T, scrpr scraper, expected int, agg pmetric.AggregationTemporality) { +func assertTransactionCount(t *testing.T, scrpr Scraper, expected int, agg pmetric.AggregationTemporality) { metrics, err := scrpr.Scrape(context.Background()) require.NoError(t, err) metric := metrics.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0) @@ -284,14 +284,14 @@ func assertTransactionCount(t *testing.T, scrpr scraper, expected int, agg pmetr } func TestScraper_Float(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{ {{"myfloat": "123.4"}}, }, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.float", ValueColumn: "myfloat", @@ -308,14 +308,14 @@ func TestScraper_Float(t *testing.T) { } func TestScraper_DescriptionAndUnit(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{ {{"mycol": "123"}}, }, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.name", ValueColumn: "mycol", @@ -334,10 +334,10 @@ func TestScraper_DescriptionAndUnit(t *testing.T) { func TestScraper_FakeDB_Warnings(t *testing.T) { db := fakeDB{rowVals: [][]any{{42, nil}}} logger := zap.NewNop() - scrpr := scraper{ - client: newDbClient(db, "", logger, TelemetryConfig{}), - logger: logger, - query: Query{ + scrpr := Scraper{ + Client: NewDbClient(db, "", logger, TelemetryConfig{}), + Logger: logger, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.name", ValueColumn: "col_0", @@ -353,10 +353,10 @@ func TestScraper_FakeDB_Warnings(t *testing.T) { func TestScraper_FakeDB_MultiRows_Warnings(t *testing.T) { db := fakeDB{rowVals: [][]any{{42, nil}, {43, nil}}} logger := zap.NewNop() - scrpr := scraper{ - client: newDbClient(db, "", logger, TelemetryConfig{}), - logger: logger, - query: Query{ + scrpr := Scraper{ + Client: NewDbClient(db, "", logger, TelemetryConfig{}), + Logger: logger, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.col.0", ValueColumn: "col_0", @@ -374,10 +374,10 @@ func TestScraper_FakeDB_MultiRows_Warnings(t *testing.T) { func TestScraper_FakeDB_MultiRows_Error(t *testing.T) { db := fakeDB{rowVals: [][]any{{42, nil}, {43, nil}}} logger := zap.NewNop() - scrpr := scraper{ - client: newDbClient(db, "", logger, TelemetryConfig{}), - logger: logger, - query: Query{ + scrpr := Scraper{ + Client: NewDbClient(db, "", logger, TelemetryConfig{}), + Logger: logger, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.col.0", ValueColumn: "col_0", @@ -395,14 +395,14 @@ func TestScraper_FakeDB_MultiRows_Error(t *testing.T) { _, err := scrpr.Scrape(context.Background()) // We expect an error here not directly because of the NULL values but because // the column was also requested in Query.Metrics[1] but wasn't found. It's just - // a partial scrape error though so it shouldn't cause a scraper shutdown. + // a partial scrape error though so it shouldn't cause a Scraper shutdown. assert.Error(t, err) assert.True(t, scrapererror.IsPartialScrapeError(err)) } func TestScraper_StartAndTSColumn(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{{ { "mycol": "42", "StartTs": "1682417791", @@ -410,9 +410,9 @@ func TestScraper_StartAndTSColumn(t *testing.T) { }, }}, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.name", ValueColumn: "mycol", @@ -431,17 +431,17 @@ func TestScraper_StartAndTSColumn(t *testing.T) { } func TestScraper_StartAndTS_ErrorOnColumnNotFound(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{{ { "mycol": "42", "StartTs": "1682417791", }, }}, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.name", ValueColumn: "mycol", @@ -457,17 +457,17 @@ func TestScraper_StartAndTS_ErrorOnColumnNotFound(t *testing.T) { } func TestScraper_StartAndTS_ErrorOnParse(t *testing.T) { - client := &fakeDBClient{ - stringMaps: [][]stringMap{{ + client := &FakeDBClient{ + StringMaps: [][]StringMap{{ { "mycol": "42", "StartTs": "blah", }, }}, } - scrpr := scraper{ - client: client, - query: Query{ + scrpr := Scraper{ + Client: client, + Query: Query{ Metrics: []MetricCfg{{ MetricName: "my.name", ValueColumn: "mycol", diff --git a/receiver/sqlqueryreceiver/config.go b/receiver/sqlqueryreceiver/config.go index 5b37abf5f58a..d83427f37365 100644 --- a/receiver/sqlqueryreceiver/config.go +++ b/receiver/sqlqueryreceiver/config.go @@ -4,186 +4,29 @@ package sqlqueryreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver" import ( - "errors" - "fmt" "time" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/receiver/scraperhelper" - "go.uber.org/multierr" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver/internal/metadata" ) type Config struct { - scraperhelper.ScraperControllerSettings `mapstructure:",squash"` - Driver string `mapstructure:"driver"` - DataSource string `mapstructure:"datasource"` - Queries []Query `mapstructure:"queries"` - StorageID *component.ID `mapstructure:"storage"` - Telemetry TelemetryConfig `mapstructure:"telemetry"` + sqlquery.Config `mapstructure:",squash"` } func (c Config) Validate() error { - if c.Driver == "" { - return errors.New("'driver' cannot be empty") - } - if c.DataSource == "" { - return errors.New("'datasource' cannot be empty") - } - if len(c.Queries) == 0 { - return errors.New("'queries' cannot be empty") - } - for _, query := range c.Queries { - if err := query.Validate(); err != nil { - return err - } - } return nil } -type Query struct { - SQL string `mapstructure:"sql"` - Metrics []MetricCfg `mapstructure:"metrics"` - Logs []LogsCfg `mapstructure:"logs"` - TrackingColumn string `mapstructure:"tracking_column"` - TrackingStartValue string `mapstructure:"tracking_start_value"` -} - -func (q Query) Validate() error { - var errs error - if q.SQL == "" { - errs = multierr.Append(errs, errors.New("'query.sql' cannot be empty")) - } - if len(q.Logs) == 0 && len(q.Metrics) == 0 { - errs = multierr.Append(errs, errors.New("at least one of 'query.logs' and 'query.metrics' must not be empty")) - } - for _, logs := range q.Logs { - if err := logs.Validate(); err != nil { - errs = multierr.Append(errs, err) - } - } - for _, metric := range q.Metrics { - if err := metric.Validate(); err != nil { - errs = multierr.Append(errs, err) - } - } - return errs -} - -type LogsCfg struct { - BodyColumn string `mapstructure:"body_column"` -} - -func (config LogsCfg) Validate() error { - var errs error - if config.BodyColumn == "" { - errs = multierr.Append(errs, errors.New("'body_column' must not be empty")) - } - return errs -} - -type MetricCfg struct { - MetricName string `mapstructure:"metric_name"` - ValueColumn string `mapstructure:"value_column"` - AttributeColumns []string `mapstructure:"attribute_columns"` - Monotonic bool `mapstructure:"monotonic"` - ValueType MetricValueType `mapstructure:"value_type"` - DataType MetricType `mapstructure:"data_type"` - Aggregation MetricAggregation `mapstructure:"aggregation"` - Unit string `mapstructure:"unit"` - Description string `mapstructure:"description"` - StaticAttributes map[string]string `mapstructure:"static_attributes"` - StartTsColumn string `mapstructure:"start_ts_column"` - TsColumn string `mapstructure:"ts_column"` -} - -func (c MetricCfg) Validate() error { - var errs error - if c.MetricName == "" { - errs = multierr.Append(errs, errors.New("'metric_name' cannot be empty")) - } - if c.ValueColumn == "" { - errs = multierr.Append(errs, errors.New("'value_column' cannot be empty")) - } - if err := c.ValueType.Validate(); err != nil { - errs = multierr.Append(errs, err) - } - if err := c.DataType.Validate(); err != nil { - errs = multierr.Append(errs, err) - } - if err := c.Aggregation.Validate(); err != nil { - errs = multierr.Append(errs, err) - } - if c.DataType == MetricTypeGauge && c.Aggregation != "" { - errs = multierr.Append(errs, fmt.Errorf("aggregation=%s but data_type=%s does not support aggregation", c.Aggregation, c.DataType)) - } - if errs != nil && c.MetricName != "" { - errs = multierr.Append(fmt.Errorf("invalid metric config with metric_name '%s'", c.MetricName), errs) - } - return errs -} - -type MetricType string - -const ( - MetricTypeUnspecified MetricType = "" - MetricTypeGauge MetricType = "gauge" - MetricTypeSum MetricType = "sum" -) - -func (t MetricType) Validate() error { - switch t { - case MetricTypeUnspecified, MetricTypeGauge, MetricTypeSum: - return nil - } - return fmt.Errorf("metric config has unsupported data_type: '%s'", t) -} - -type MetricValueType string - -const ( - MetricValueTypeUnspecified MetricValueType = "" - MetricValueTypeInt MetricValueType = "int" - MetricValueTypeDouble MetricValueType = "double" -) - -func (t MetricValueType) Validate() error { - switch t { - case MetricValueTypeUnspecified, MetricValueTypeInt, MetricValueTypeDouble: - return nil - } - return fmt.Errorf("metric config has unsupported value_type: '%s'", t) -} - -type MetricAggregation string - -const ( - MetricAggregationUnspecified MetricAggregation = "" - MetricAggregationCumulative MetricAggregation = "cumulative" - MetricAggregationDelta MetricAggregation = "delta" -) - -func (a MetricAggregation) Validate() error { - switch a { - case MetricAggregationUnspecified, MetricAggregationCumulative, MetricAggregationDelta: - return nil - } - return fmt.Errorf("metric config has unsupported aggregation: '%s'", a) -} - func createDefaultConfig() component.Config { cfg := scraperhelper.NewDefaultScraperControllerSettings(metadata.Type) cfg.CollectionInterval = 10 * time.Second return &Config{ - ScraperControllerSettings: cfg, + Config: sqlquery.Config{ + ScraperControllerSettings: cfg, + }, } } - -type TelemetryConfig struct { - Logs TelemetryLogsConfig `mapstructure:"logs"` -} - -type TelemetryLogsConfig struct { - Query bool `mapstructure:"query"` -} diff --git a/receiver/sqlqueryreceiver/config_test.go b/receiver/sqlqueryreceiver/config_test.go index 56893e428f94..d4d4e11b2f7f 100644 --- a/receiver/sqlqueryreceiver/config_test.go +++ b/receiver/sqlqueryreceiver/config_test.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/receiver/scraperhelper" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver/internal/metadata" ) @@ -30,25 +31,27 @@ func TestLoadConfig(t *testing.T) { id: component.NewIDWithName(metadata.Type, ""), fname: "config.yaml", expected: &Config{ - ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ - CollectionInterval: 10 * time.Second, - InitialDelay: time.Second, - }, - Driver: "mydriver", - DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable", - Queries: []Query{ - { - SQL: "select count(*) as count, type from mytable group by type", - Metrics: []MetricCfg{ - { - MetricName: "val.count", - ValueColumn: "count", - AttributeColumns: []string{"type"}, - Monotonic: false, - ValueType: MetricValueTypeInt, - DataType: MetricTypeSum, - Aggregation: MetricAggregationCumulative, - StaticAttributes: map[string]string{"foo": "bar"}, + Config: sqlquery.Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + CollectionInterval: 10 * time.Second, + InitialDelay: time.Second, + }, + Driver: "mydriver", + DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable", + Queries: []sqlquery.Query{ + { + SQL: "select count(*) as count, type from mytable group by type", + Metrics: []sqlquery.MetricCfg{ + { + MetricName: "val.count", + ValueColumn: "count", + AttributeColumns: []string{"type"}, + Monotonic: false, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeSum, + Aggregation: sqlquery.MetricAggregationCumulative, + StaticAttributes: map[string]string{"foo": "bar"}, + }, }, }, }, @@ -109,20 +112,22 @@ func TestLoadConfig(t *testing.T) { fname: "config-logs.yaml", id: component.NewIDWithName(metadata.Type, ""), expected: &Config{ - ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ - CollectionInterval: 10 * time.Second, - InitialDelay: time.Second, - }, - Driver: "mydriver", - DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable", - Queries: []Query{ - { - SQL: "select * from test_logs where log_id > ?", - TrackingColumn: "log_id", - TrackingStartValue: "10", - Logs: []LogsCfg{ - { - BodyColumn: "log_body", + Config: sqlquery.Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + CollectionInterval: 10 * time.Second, + InitialDelay: time.Second, + }, + Driver: "mydriver", + DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable", + Queries: []sqlquery.Query{ + { + SQL: "select * from test_logs where log_id > ?", + TrackingColumn: "log_id", + TrackingStartValue: "10", + Logs: []sqlquery.LogsCfg{ + { + BodyColumn: "log_body", + }, }, }, }, @@ -165,7 +170,7 @@ func TestLoadConfig(t *testing.T) { func TestCreateDefaultConfig(t *testing.T) { cfg := createDefaultConfig().(*Config) - assert.Equal(t, 10*time.Second, cfg.ScraperControllerSettings.CollectionInterval) + assert.Equal(t, 10*time.Second, cfg.Config.ScraperControllerSettings.CollectionInterval) } func TestConfig_Validate_Multierr(t *testing.T) { diff --git a/receiver/sqlqueryreceiver/db_client.go b/receiver/sqlqueryreceiver/db_client.go deleted file mode 100644 index 2afa56f3e51e..000000000000 --- a/receiver/sqlqueryreceiver/db_client.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package sqlqueryreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver" - -import ( - "context" - - // register db drivers - _ "github.com/SAP/go-hdb/driver" - _ "github.com/go-sql-driver/mysql" - _ "github.com/lib/pq" - _ "github.com/microsoft/go-mssqldb" - _ "github.com/microsoft/go-mssqldb/integratedauth/krb5" - _ "github.com/sijms/go-ora/v2" - _ "github.com/snowflakedb/gosnowflake" - "go.uber.org/multierr" - "go.uber.org/zap" -) - -type stringMap map[string]string - -type dbClient interface { - queryRows(ctx context.Context, args ...any) ([]stringMap, error) -} - -type dbSQLClient struct { - db db - logger *zap.Logger - telemetryConfig TelemetryConfig - sql string -} - -func newDbClient(db db, sql string, logger *zap.Logger, telemetryConfig TelemetryConfig) dbClient { - return dbSQLClient{ - db: db, - sql: sql, - logger: logger, - telemetryConfig: telemetryConfig, - } -} - -func (cl dbSQLClient) queryRows(ctx context.Context, args ...any) ([]stringMap, error) { - cl.logger.Debug("Running query", cl.prepareQueryFields(cl.sql, args)...) - sqlRows, err := cl.db.QueryContext(ctx, cl.sql, args...) - if err != nil { - return nil, err - } - var out []stringMap - colTypes, err := sqlRows.ColumnTypes() - if err != nil { - return nil, err - } - scanner := newRowScanner(colTypes) - var warnings error - for sqlRows.Next() { - err = scanner.scan(sqlRows) - if err != nil { - return nil, err - } - sm, scanErr := scanner.toStringMap() - if scanErr != nil { - warnings = multierr.Append(warnings, scanErr) - } - out = append(out, sm) - } - return out, warnings -} - -func (cl dbSQLClient) prepareQueryFields(sql string, args []any) []zap.Field { - var logFields []zap.Field - if cl.telemetryConfig.Logs.Query { - logFields = append(logFields, zap.String("query", sql)) - logFields = append(logFields, zap.Any("parameters", args)) - } - return logFields -} diff --git a/receiver/sqlqueryreceiver/factory.go b/receiver/sqlqueryreceiver/factory.go index b72c1c37a2f2..2b31320b98d9 100644 --- a/receiver/sqlqueryreceiver/factory.go +++ b/receiver/sqlqueryreceiver/factory.go @@ -8,6 +8,7 @@ import ( "go.opentelemetry.io/collector/receiver" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver/internal/metadata" ) @@ -15,7 +16,7 @@ func NewFactory() receiver.Factory { return receiver.NewFactory( metadata.Type, createDefaultConfig, - receiver.WithLogs(createLogsReceiverFunc(sql.Open, newDbClient), metadata.LogsStability), - receiver.WithMetrics(createMetricsReceiverFunc(sql.Open, newDbClient), metadata.MetricsStability), + receiver.WithLogs(createLogsReceiverFunc(sql.Open, sqlquery.NewDbClient), metadata.LogsStability), + receiver.WithMetrics(createMetricsReceiverFunc(sql.Open, sqlquery.NewDbClient), metadata.MetricsStability), ) } diff --git a/receiver/sqlqueryreceiver/go.mod b/receiver/sqlqueryreceiver/go.mod index 74e5fcb13a68..77d1d78e48ec 100644 --- a/receiver/sqlqueryreceiver/go.mod +++ b/receiver/sqlqueryreceiver/go.mod @@ -3,17 +3,12 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlque go 1.20 require ( - github.com/SAP/go-hdb v1.7.11 github.com/docker/go-connections v0.5.0 - github.com/go-sql-driver/mysql v1.7.1 - github.com/lib/pq v1.10.9 - github.com/microsoft/go-mssqldb v1.6.0 github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.93.0 github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.93.0 + github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery v0.93.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.93.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.93.0 - github.com/sijms/go-ora/v2 v2.8.6 - github.com/snowflakedb/gosnowflake v1.7.2 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.27.0 go.opentelemetry.io/collector/component v0.93.1-0.20240130182548-89388addcc7f @@ -39,6 +34,7 @@ require ( github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/SAP/go-hdb v1.7.11 // indirect github.com/apache/arrow/go/v14 v14.0.2 // indirect github.com/aws/aws-sdk-go-v2 v1.22.2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect @@ -71,6 +67,7 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -97,8 +94,10 @@ require ( github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.0.1 // indirect github.com/leodido/ragel-machinery v0.0.0-20181214104525-299bdde78165 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/microsoft/go-mssqldb v1.6.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -125,7 +124,9 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/shirou/gopsutil/v3 v3.23.12 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sijms/go-ora/v2 v2.8.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/snowflakedb/gosnowflake v1.7.2 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/valyala/fastjson v1.6.4 // indirect @@ -178,3 +179,5 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza => replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden => ../../pkg/golden + +replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery => ../../internal/sqlquery diff --git a/receiver/sqlqueryreceiver/integration_test.go b/receiver/sqlqueryreceiver/integration_test.go index fe154e3a299d..f8ba19dc4737 100644 --- a/receiver/sqlqueryreceiver/integration_test.go +++ b/receiver/sqlqueryreceiver/integration_test.go @@ -29,6 +29,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/storagetest" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/scraperinttest" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" ) @@ -49,10 +50,10 @@ func TestPostgresIntegrationLogsTrackingWithoutStorage(t *testing.T) { // Start the SQL Query receiver. receiver, config, consumer := createTestLogsReceiverForPostgres(t, externalPort) config.CollectionInterval = time.Second - config.Queries = []Query{ + config.Queries = []sqlquery.Query{ { SQL: "select * from simple_logs where id > $1", - Logs: []LogsCfg{ + Logs: []sqlquery.LogsCfg{ { BodyColumn: "body", }, @@ -85,10 +86,10 @@ func TestPostgresIntegrationLogsTrackingWithoutStorage(t *testing.T) { // Start new SQL Query receiver with the same configuration. receiver, config, consumer = createTestLogsReceiverForPostgres(t, externalPort) config.CollectionInterval = time.Second - config.Queries = []Query{ + config.Queries = []sqlquery.Query{ { SQL: "select * from simple_logs where id > $1", - Logs: []LogsCfg{ + Logs: []sqlquery.LogsCfg{ { BodyColumn: "body", }, @@ -136,10 +137,10 @@ func TestPostgresIntegrationLogsTrackingWithStorage(t *testing.T) { receiver, config, consumer := createTestLogsReceiverForPostgres(t, externalPort) config.CollectionInterval = time.Second config.StorageID = &storageExtension.ID - config.Queries = []Query{ + config.Queries = []sqlquery.Query{ { SQL: "select * from simple_logs where id > $1", - Logs: []LogsCfg{ + Logs: []sqlquery.LogsCfg{ { BodyColumn: "body", }, @@ -178,10 +179,10 @@ func TestPostgresIntegrationLogsTrackingWithStorage(t *testing.T) { receiver, config, consumer = createTestLogsReceiverForPostgres(t, externalPort) config.CollectionInterval = time.Second config.StorageID = &storageExtension.ID - config.Queries = []Query{ + config.Queries = []sqlquery.Query{ { SQL: "select * from simple_logs where id > $1", - Logs: []LogsCfg{ + Logs: []sqlquery.LogsCfg{ { BodyColumn: "body", }, @@ -211,10 +212,10 @@ func TestPostgresIntegrationLogsTrackingWithStorage(t *testing.T) { receiver, config, consumer = createTestLogsReceiverForPostgres(t, externalPort) config.CollectionInterval = time.Second config.StorageID = &storageExtension.ID - config.Queries = []Query{ + config.Queries = []sqlquery.Query{ { SQL: "select * from simple_logs where id > $1", - Logs: []LogsCfg{ + Logs: []sqlquery.LogsCfg{ { BodyColumn: "body", }, @@ -354,77 +355,77 @@ func TestPostgresqlIntegrationMetrics(t *testing.T) { rCfg.Driver = "postgres" rCfg.DataSource = fmt.Sprintf("host=%s port=%s user=otel password=otel sslmode=disable", ci.Host(t), ci.MappedPort(t, postgresqlPort)) - rCfg.Queries = []Query{ + rCfg.Queries = []sqlquery.Query{ { SQL: "select genre, count(*), avg(imdb_rating) from movie group by genre", - Metrics: []MetricCfg{ + Metrics: []sqlquery.MetricCfg{ { MetricName: "genre.count", ValueColumn: "count", AttributeColumns: []string{"genre"}, - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "genre.imdb", ValueColumn: "avg", AttributeColumns: []string{"genre"}, - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, }, }, { SQL: "select 1::smallint as a, 2::integer as b, 3::bigint as c, 4.1::decimal as d," + " 4.2::numeric as e, 4.3::real as f, 4.4::double precision as g, null as h", - Metrics: []MetricCfg{ + Metrics: []sqlquery.MetricCfg{ { MetricName: "a", ValueColumn: "a", - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "b", ValueColumn: "b", - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "c", ValueColumn: "c", - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "d", ValueColumn: "d", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "e", ValueColumn: "e", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "f", ValueColumn: "f", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "g", ValueColumn: "g", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "h", ValueColumn: "h", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, }, }, @@ -467,23 +468,23 @@ func TestOracleDBIntegrationMetrics(t *testing.T) { rCfg.Driver = "oracle" rCfg.DataSource = fmt.Sprintf("oracle://otel:p@ssw%%25rd@%s:%s/XE", ci.Host(t), ci.MappedPort(t, oraclePort)) - rCfg.Queries = []Query{ + rCfg.Queries = []sqlquery.Query{ { SQL: "select genre, count(*) as count, avg(imdb_rating) as avg from sys.movie group by genre", - Metrics: []MetricCfg{ + Metrics: []sqlquery.MetricCfg{ { MetricName: "genre.count", ValueColumn: "COUNT", AttributeColumns: []string{"GENRE"}, - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "genre.imdb", ValueColumn: "AVG", AttributeColumns: []string{"GENRE"}, - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, }, }, @@ -524,23 +525,23 @@ func TestMysqlIntegrationMetrics(t *testing.T) { rCfg.Driver = "mysql" rCfg.DataSource = fmt.Sprintf("otel:otel@tcp(%s:%s)/otel", ci.Host(t), ci.MappedPort(t, mysqlPort)) - rCfg.Queries = []Query{ + rCfg.Queries = []sqlquery.Query{ { SQL: "select genre, count(*), avg(imdb_rating) from movie group by genre", - Metrics: []MetricCfg{ + Metrics: []sqlquery.MetricCfg{ { MetricName: "genre.count", ValueColumn: "count(*)", AttributeColumns: []string{"genre"}, - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "genre.imdb", ValueColumn: "avg(imdb_rating)", AttributeColumns: []string{"genre"}, - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, }, }, @@ -553,42 +554,42 @@ func TestMysqlIntegrationMetrics(t *testing.T) { "cast(3.3 as float) as e, " + "cast(3.4 as double) as f, " + "null as g", - Metrics: []MetricCfg{ + Metrics: []sqlquery.MetricCfg{ { MetricName: "a", ValueColumn: "a", - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "b", ValueColumn: "b", - ValueType: MetricValueTypeInt, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeInt, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "c", ValueColumn: "c", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "d", ValueColumn: "d", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "e", ValueColumn: "e", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, { MetricName: "f", ValueColumn: "f", - ValueType: MetricValueTypeDouble, - DataType: MetricTypeGauge, + ValueType: sqlquery.MetricValueTypeDouble, + DataType: sqlquery.MetricTypeGauge, }, }, }, diff --git a/receiver/sqlqueryreceiver/logs_receiver.go b/receiver/sqlqueryreceiver/logs_receiver.go index fb24433b5177..7372f8dcd47f 100644 --- a/receiver/sqlqueryreceiver/logs_receiver.go +++ b/receiver/sqlqueryreceiver/logs_receiver.go @@ -19,6 +19,7 @@ import ( "go.uber.org/multierr" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/adapter" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver/internal/metadata" ) @@ -26,8 +27,8 @@ import ( type logsReceiver struct { config *Config settings receiver.CreateSettings - createConnection dbProviderFunc - createClient clientProviderFunc + createConnection sqlquery.DbProviderFunc + createClient sqlquery.ClientProviderFunc queryReceivers []*logsQueryReceiver nextConsumer consumer.Logs @@ -43,8 +44,8 @@ type logsReceiver struct { func newLogsReceiver( config *Config, settings receiver.CreateSettings, - sqlOpenerFunc sqlOpenerFunc, - createClient clientProviderFunc, + sqlOpenerFunc sqlquery.SQLOpenerFunc, + createClient sqlquery.ClientProviderFunc, nextConsumer consumer.Logs, ) (*logsReceiver, error) { @@ -199,14 +200,14 @@ func (receiver *logsReceiver) stopCollecting() { type logsQueryReceiver struct { id string - query Query - createDb dbProviderFunc - createClient clientProviderFunc + query sqlquery.Query + createDb sqlquery.DbProviderFunc + createClient sqlquery.ClientProviderFunc logger *zap.Logger - telemetry TelemetryConfig + telemetry sqlquery.TelemetryConfig db *sql.DB - client dbClient + client sqlquery.DbClient trackingValue string // TODO: Extract persistence into its own component storageClient storage.Client @@ -215,11 +216,11 @@ type logsQueryReceiver struct { func newLogsQueryReceiver( id string, - query Query, - dbProviderFunc dbProviderFunc, - clientProviderFunc clientProviderFunc, + query sqlquery.Query, + dbProviderFunc sqlquery.DbProviderFunc, + clientProviderFunc sqlquery.ClientProviderFunc, logger *zap.Logger, - telemetry TelemetryConfig, + telemetry sqlquery.TelemetryConfig, storageClient storage.Client, ) *logsQueryReceiver { queryReceiver := &logsQueryReceiver{ @@ -246,7 +247,7 @@ func (queryReceiver *logsQueryReceiver) start(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to open db connection: %w", err) } - queryReceiver.client = queryReceiver.createClient(dbWrapper{queryReceiver.db}, queryReceiver.query.SQL, queryReceiver.logger, queryReceiver.telemetry) + queryReceiver.client = queryReceiver.createClient(sqlquery.DbWrapper{Db: queryReceiver.db}, queryReceiver.query.SQL, queryReceiver.logger, queryReceiver.telemetry) queryReceiver.trackingValue = queryReceiver.retrieveTrackingValue(ctx) @@ -273,13 +274,13 @@ func (queryReceiver *logsQueryReceiver) retrieveTrackingValue(ctx context.Contex func (queryReceiver *logsQueryReceiver) collect(ctx context.Context) (plog.Logs, error) { logs := plog.NewLogs() - var rows []stringMap + var rows []sqlquery.StringMap var err error observedAt := pcommon.NewTimestampFromTime(time.Now()) if queryReceiver.query.TrackingColumn != "" { - rows, err = queryReceiver.client.queryRows(ctx, queryReceiver.trackingValue) + rows, err = queryReceiver.client.QueryRows(ctx, queryReceiver.trackingValue) } else { - rows, err = queryReceiver.client.queryRows(ctx) + rows, err = queryReceiver.client.QueryRows(ctx) } if err != nil { return logs, fmt.Errorf("error getting rows: %w", err) @@ -300,7 +301,7 @@ func (queryReceiver *logsQueryReceiver) collect(ctx context.Context) (plog.Logs, return logs, nil } -func (queryReceiver *logsQueryReceiver) storeTrackingValue(ctx context.Context, row stringMap) error { +func (queryReceiver *logsQueryReceiver) storeTrackingValue(ctx context.Context, row sqlquery.StringMap) error { if queryReceiver.query.TrackingColumn == "" { return nil } @@ -314,7 +315,7 @@ func (queryReceiver *logsQueryReceiver) storeTrackingValue(ctx context.Context, return nil } -func rowToLog(row stringMap, config LogsCfg, logRecord plog.LogRecord) { +func rowToLog(row sqlquery.StringMap, config sqlquery.LogsCfg, logRecord plog.LogRecord) { logRecord.Body().SetStr(row[config.BodyColumn]) } diff --git a/receiver/sqlqueryreceiver/logs_receiver_test.go b/receiver/sqlqueryreceiver/logs_receiver_test.go index b78b698bc898..34877c23ce23 100644 --- a/receiver/sqlqueryreceiver/logs_receiver_test.go +++ b/receiver/sqlqueryreceiver/logs_receiver_test.go @@ -10,20 +10,22 @@ import ( "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/pdata/pcommon" + + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" ) func TestLogsQueryReceiver_Collect(t *testing.T) { now := time.Now() - fakeClient := &fakeDBClient{ - stringMaps: [][]stringMap{ + fakeClient := &sqlquery.FakeDBClient{ + StringMaps: [][]sqlquery.StringMap{ {{"col1": "42"}, {"col1": "63"}}, }, } queryReceiver := logsQueryReceiver{ client: fakeClient, - query: Query{ - Logs: []LogsCfg{ + query: sqlquery.Query{ + Logs: []sqlquery.LogsCfg{ { BodyColumn: "col1", }, diff --git a/receiver/sqlqueryreceiver/receiver.go b/receiver/sqlqueryreceiver/receiver.go index 3228d51fcd9e..f9b54613e6e5 100644 --- a/receiver/sqlqueryreceiver/receiver.go +++ b/receiver/sqlqueryreceiver/receiver.go @@ -12,16 +12,11 @@ import ( "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" - "go.uber.org/zap" -) - -type sqlOpenerFunc func(driverName, dataSourceName string) (*sql.DB, error) - -type dbProviderFunc func() (*sql.DB, error) -type clientProviderFunc func(db, string, *zap.Logger, TelemetryConfig) dbClient + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" +) -func createLogsReceiverFunc(sqlOpenerFunc sqlOpenerFunc, clientProviderFunc clientProviderFunc) receiver.CreateLogsFunc { +func createLogsReceiverFunc(sqlOpenerFunc sqlquery.SQLOpenerFunc, clientProviderFunc sqlquery.ClientProviderFunc) receiver.CreateLogsFunc { return func( ctx context.Context, settings receiver.CreateSettings, @@ -33,7 +28,7 @@ func createLogsReceiverFunc(sqlOpenerFunc sqlOpenerFunc, clientProviderFunc clie } } -func createMetricsReceiverFunc(sqlOpenerFunc sqlOpenerFunc, clientProviderFunc clientProviderFunc) receiver.CreateMetricsFunc { +func createMetricsReceiverFunc(sqlOpenerFunc sqlquery.SQLOpenerFunc, clientProviderFunc sqlquery.ClientProviderFunc) receiver.CreateMetricsFunc { return func( ctx context.Context, settings receiver.CreateSettings, @@ -47,17 +42,11 @@ func createMetricsReceiverFunc(sqlOpenerFunc sqlOpenerFunc, clientProviderFunc c continue } id := component.NewIDWithName("sqlqueryreceiver", fmt.Sprintf("query-%d: %s", i, query.SQL)) - mp := &scraper{ - id: id, - query: query, - scrapeCfg: sqlCfg.ScraperControllerSettings, - logger: settings.TelemetrySettings.Logger, - telemetry: sqlCfg.Telemetry, - dbProviderFunc: func() (*sql.DB, error) { - return sqlOpenerFunc(sqlCfg.Driver, sqlCfg.DataSource) - }, - clientProviderFunc: clientProviderFunc, + dbProviderFunc := func() (*sql.DB, error) { + return sqlOpenerFunc(sqlCfg.Driver, sqlCfg.DataSource) } + mp := sqlquery.NewScraper(id, query, sqlCfg.ScraperControllerSettings, settings.TelemetrySettings.Logger, sqlCfg.Config.Telemetry, dbProviderFunc, clientProviderFunc) + opt := scraperhelper.AddScraper(mp) opts = append(opts, opt) } diff --git a/receiver/sqlqueryreceiver/receiver_test.go b/receiver/sqlqueryreceiver/receiver_test.go index 7d222bc8613b..ff5cd49f9d53 100644 --- a/receiver/sqlqueryreceiver/receiver_test.go +++ b/receiver/sqlqueryreceiver/receiver_test.go @@ -15,6 +15,8 @@ import ( "go.opentelemetry.io/collector/receiver/receivertest" "go.opentelemetry.io/collector/receiver/scraperhelper" "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery" ) func TestCreateLogsReceiver(t *testing.T) { @@ -24,17 +26,19 @@ func TestCreateLogsReceiver(t *testing.T) { ctx, receivertest.NewNopCreateSettings(), &Config{ - ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ - CollectionInterval: 10 * time.Second, - }, - Driver: "mydriver", - DataSource: "my-datasource", - Queries: []Query{{ - SQL: "select * from foo", - Logs: []LogsCfg{ - {}, + Config: sqlquery.Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + CollectionInterval: 10 * time.Second, }, - }}, + Driver: "mydriver", + DataSource: "my-datasource", + Queries: []sqlquery.Query{{ + SQL: "select * from foo", + Logs: []sqlquery.LogsCfg{ + {}, + }, + }}, + }, }, consumertest.NewNop(), ) @@ -50,19 +54,21 @@ func TestCreateMetricsReceiver(t *testing.T) { ctx, receivertest.NewNopCreateSettings(), &Config{ - ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ - CollectionInterval: 10 * time.Second, - InitialDelay: time.Second, - }, - Driver: "mydriver", - DataSource: "my-datasource", - Queries: []Query{{ - SQL: "select * from foo", - Metrics: []MetricCfg{{ - MetricName: "my-metric", - ValueColumn: "my-column", + Config: sqlquery.Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + CollectionInterval: 10 * time.Second, + InitialDelay: time.Second, + }, + Driver: "mydriver", + DataSource: "my-datasource", + Queries: []sqlquery.Query{{ + SQL: "select * from foo", + Metrics: []sqlquery.MetricCfg{{ + MetricName: "my-metric", + ValueColumn: "my-column", + }}, }}, - }}, + }, }, consumertest.NewNop(), ) @@ -75,6 +81,6 @@ func fakeDBConnect(string, string) (*sql.DB, error) { return nil, nil } -func mkFakeClient(db, string, *zap.Logger, TelemetryConfig) dbClient { - return &fakeDBClient{stringMaps: [][]stringMap{{{"foo": "111"}}}} +func mkFakeClient(sqlquery.Db, string, *zap.Logger, sqlquery.TelemetryConfig) sqlquery.DbClient { + return &sqlquery.FakeDBClient{StringMaps: [][]sqlquery.StringMap{{{"foo": "111"}}}} } diff --git a/receiver/sqlqueryreceiver/scraper.go b/receiver/sqlqueryreceiver/scraper.go deleted file mode 100644 index babd119be87f..000000000000 --- a/receiver/sqlqueryreceiver/scraper.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package sqlqueryreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlqueryreceiver" - -import ( - "context" - "database/sql" - "errors" - "fmt" - "time" - - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/pmetric" - "go.opentelemetry.io/collector/receiver/scrapererror" - "go.opentelemetry.io/collector/receiver/scraperhelper" - "go.uber.org/multierr" - "go.uber.org/zap" -) - -type scraper struct { - id component.ID - query Query - scrapeCfg scraperhelper.ScraperControllerSettings - startTime pcommon.Timestamp - clientProviderFunc clientProviderFunc - dbProviderFunc dbProviderFunc - logger *zap.Logger - telemetry TelemetryConfig - client dbClient - db *sql.DB -} - -var _ scraperhelper.Scraper = (*scraper)(nil) - -func (s *scraper) ID() component.ID { - return s.id -} - -func (s *scraper) Start(context.Context, component.Host) error { - var err error - s.db, err = s.dbProviderFunc() - if err != nil { - return fmt.Errorf("failed to open db connection: %w", err) - } - s.client = s.clientProviderFunc(dbWrapper{s.db}, s.query.SQL, s.logger, s.telemetry) - s.startTime = pcommon.NewTimestampFromTime(time.Now()) - - return nil -} - -func (s *scraper) Scrape(ctx context.Context) (pmetric.Metrics, error) { - out := pmetric.NewMetrics() - rows, err := s.client.queryRows(ctx) - if err != nil { - if errors.Is(err, errNullValueWarning) { - s.logger.Warn("problems encountered getting metric rows", zap.Error(err)) - } else { - return out, fmt.Errorf("scraper: %w", err) - } - } - ts := pcommon.NewTimestampFromTime(time.Now()) - rms := out.ResourceMetrics() - rm := rms.AppendEmpty() - sms := rm.ScopeMetrics() - sm := sms.AppendEmpty() - ms := sm.Metrics() - var errs error - for _, metricCfg := range s.query.Metrics { - for i, row := range rows { - if err = rowToMetric(row, metricCfg, ms.AppendEmpty(), s.startTime, ts, s.scrapeCfg); err != nil { - err = fmt.Errorf("row %d: %w", i, err) - errs = multierr.Append(errs, err) - } - } - } - if errs != nil { - return out, scrapererror.NewPartialScrapeError(errs, len(multierr.Errors(errs))) - } - return out, nil -} - -func (s *scraper) Shutdown(_ context.Context) error { - if s.db != nil { - return s.db.Close() - } - return nil -} diff --git a/versions.yaml b/versions.yaml index 461476187f9a..71d5e1a15d2c 100644 --- a/versions.yaml +++ b/versions.yaml @@ -119,6 +119,7 @@ module-sets: - github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders - github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent - github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk + - github.com/open-telemetry/opentelemetry-collector-contrib/internal/sqlquery - github.com/open-telemetry/opentelemetry-collector-contrib/internal/datadog - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal