diff --git a/receiver/sqlqueryreceiver/README.md b/receiver/sqlqueryreceiver/README.md index 570d4d9c8879..e5d467558917 100644 --- a/receiver/sqlqueryreceiver/README.md +++ b/receiver/sqlqueryreceiver/README.md @@ -21,12 +21,41 @@ The configuration supports the following top-level fields: a driver-specific string usually consisting of at least a database name and connection information. This is sometimes referred to as the "connection string" in driver documentation. e.g. _host=localhost port=5432 user=me password=s3cr3t sslmode=disable_ -- `queries`(required): A list of queries, where a query is a sql statement and one or more metrics (details below). +- `queries`(required): A list of queries, where a query is a sql statement and one or more `logs` and/or `metrics` sections (details below). - `collection_interval`(optional): The time interval between query executions. Defaults to _10s_. ### Queries -A _query_ consists of a sql statement and one or more _metrics_, where each metric consists of a +A _query_ consists of a sql statement and one or more `logs` and/or `metrics` section. +At least one `logs` or one `metrics` section is required. +Note that technically you can put both `logs` and `metrics` sections in a single query section, +but it's probably not a real world use case, as the requirements for logs and metrics queries +are quite different. + +Example: + +```yaml +receivers: + sqlquery: + driver: postgres + datasource: "host=localhost port=5432 user=postgres password=s3cr3t sslmode=disable" + queries: + - sql: "select * from my_logs" + logs: + - {} + - sql: "select count(*) as count, genre from movie group by genre" + metrics: + - metric_name: movie.genres + value_column: "count" +``` + +#### Logs Queries + +The `logs` section currently has no options. This section is in development. + +#### Metrics queries + +Each `metrics` section consists of a `metric_name`, a `value_column`, and additional optional fields. Each _metric_ in the configuration will produce one OTel metric per row returned from its sql query. @@ -53,6 +82,8 @@ receivers: driver: postgres datasource: "host=localhost port=5432 user=postgres password=s3cr3t sslmode=disable" queries: + - sql: "select * from my_logs" + logs: {} - sql: "select count(*) as count, genre from movie group by genre" metrics: - metric_name: movie.genres diff --git a/receiver/sqlqueryreceiver/config.go b/receiver/sqlqueryreceiver/config.go index 975c2ea6f3a2..2694c55e6c02 100644 --- a/receiver/sqlqueryreceiver/config.go +++ b/receiver/sqlqueryreceiver/config.go @@ -52,6 +52,7 @@ func (c Config) Validate() error { type Query struct { SQL string `mapstructure:"sql"` Metrics []MetricCfg `mapstructure:"metrics"` + Logs []LogsCfg `mapstructure:"logs"` } func (q Query) Validate() error { @@ -59,8 +60,13 @@ func (q Query) Validate() error { if q.SQL == "" { errs = multierr.Append(errs, errors.New("'query.sql' cannot be empty")) } - if len(q.Metrics) == 0 { - errs = multierr.Append(errs, errors.New("'query.metrics' 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 { @@ -70,6 +76,14 @@ func (q Query) Validate() error { return errs } +type LogsCfg struct { +} + +func (config LogsCfg) Validate() error { + var errs error + return errs +} + type MetricCfg struct { MetricName string `mapstructure:"metric_name"` ValueColumn string `mapstructure:"value_column"` diff --git a/receiver/sqlqueryreceiver/config_test.go b/receiver/sqlqueryreceiver/config_test.go index 2bc322a26145..2c38fe63758f 100644 --- a/receiver/sqlqueryreceiver/config_test.go +++ b/receiver/sqlqueryreceiver/config_test.go @@ -104,15 +104,34 @@ func TestLoadConfig(t *testing.T) { errorMessage: "'driver' cannot be empty", }, { - fname: "config-invalid-missing-metrics.yaml", + fname: "config-invalid-missing-logs-metrics.yaml", id: component.NewIDWithName(typeStr, ""), - errorMessage: "'query.metrics' cannot be empty", + errorMessage: "at least one of 'query.logs' and 'query.metrics' must not be empty", }, { fname: "config-invalid-missing-datasource.yaml", id: component.NewIDWithName(typeStr, ""), errorMessage: "'datasource' cannot be empty", }, + { + fname: "config-logs.yaml", + id: component.NewIDWithName(typeStr, ""), + expected: &Config{ + ScraperControllerSettings: scraperhelper.ScraperControllerSettings{ + CollectionInterval: 10 * time.Second, + }, + Driver: "mydriver", + DataSource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable", + Queries: []Query{ + { + SQL: "select * from test_logs", + Logs: []LogsCfg{ + {}, + }, + }, + }, + }, + }, { fname: "config-unnecessary-aggregation.yaml", id: component.NewIDWithName(typeStr, ""), @@ -121,7 +140,7 @@ func TestLoadConfig(t *testing.T) { } for _, tt := range tests { - t.Run(tt.id.String(), func(t *testing.T) { + t.Run(tt.fname, func(t *testing.T) { cm, err := confmaptest.LoadConf(filepath.Join("testdata", tt.fname)) require.NoError(t, err) diff --git a/receiver/sqlqueryreceiver/testdata/config-invalid-missing-metrics.yaml b/receiver/sqlqueryreceiver/testdata/config-invalid-missing-logs-metrics.yaml similarity index 100% rename from receiver/sqlqueryreceiver/testdata/config-invalid-missing-metrics.yaml rename to receiver/sqlqueryreceiver/testdata/config-invalid-missing-logs-metrics.yaml diff --git a/receiver/sqlqueryreceiver/testdata/config-logs.yaml b/receiver/sqlqueryreceiver/testdata/config-logs.yaml new file mode 100644 index 000000000000..3d52afa9fad5 --- /dev/null +++ b/receiver/sqlqueryreceiver/testdata/config-logs.yaml @@ -0,0 +1,8 @@ +sqlquery: + collection_interval: 10s + driver: mydriver + datasource: "host=localhost port=5432 user=me password=s3cr3t sslmode=disable" + queries: + - sql: "select * from test_logs" + logs: + - {}