From 17416fd12a861e3698587727de2480cd9598b35f Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Fri, 5 Mar 2021 16:23:41 -0500 Subject: [PATCH 1/2] Change entry.Labels to entry.Attributes --- CHANGELOG.md | 4 +- docs/operators/file_input.md | 4 +- docs/operators/filter.md | 2 +- docs/operators/host_metadata.md | 2 +- docs/operators/journald_input.md | 4 +- docs/operators/k8s_event_input.md | 6 +- docs/operators/k8s_metadata_decorator.md | 6 +- docs/operators/metadata.md | 34 ++++----- docs/operators/router.md | 10 +-- docs/operators/syslog_input.md | 18 ++--- docs/operators/tcp_input.md | 4 +- docs/operators/udp_input.md | 4 +- docs/operators/windows_eventlog_input.md | 4 +- docs/types/entry.md | 4 +- docs/types/expression.md | 4 +- docs/types/field.md | 18 ++--- entry/attribute_field.go | 71 ++++++++++++++++++ ..._field_test.go => attribute_field_test.go} | 62 ++++++++-------- entry/entry.go | 14 ++-- entry/entry_test.go | 28 +++---- entry/field.go | 12 +-- entry/field_test.go | 12 +-- entry/label_field.go | 71 ------------------ examples/tomcat/config.yaml | 2 +- internal/tools/.vscode/settings.json | 3 + internal/tools/go.mod | 6 +- internal/tools/go.sum | 42 ++++++++++- internal/tools/tools.go | 2 +- operator/builtin/input/file/config.go | 4 +- operator/builtin/input/file/config_test.go | 28 +++---- operator/builtin/input/file/file_test.go | 6 +- operator/builtin/input/k8sevent/go.sum | 2 + operator/builtin/input/k8sevent/k8s_event.go | 2 +- .../builtin/transformer/filter/filter_test.go | 10 +-- .../transformer/hostmetadata/host_metadata.go | 2 +- .../builtin/transformer/k8smetadata/go.sum | 2 + .../k8smetadata/k8s_metadata_decorator.go | 26 +++---- .../k8s_metadata_decorator_test.go | 10 +-- .../builtin/transformer/metadata/metadata.go | 18 ++--- .../transformer/metadata/metadata_test.go | 20 ++--- .../builtin/transformer/noop/noop_test.go | 2 +- operator/builtin/transformer/router/router.go | 16 ++-- .../builtin/transformer/router/router_test.go | 44 +++++------ operator/helper/attributer.go | 74 +++++++++++++++++++ .../{labeler_test.go => attributer_test.go} | 40 +++++----- operator/helper/expr_string.go | 2 +- operator/helper/host_identifier.go | 2 +- operator/helper/host_identifier_test.go | 2 +- operator/helper/identifier_test.go | 6 +- operator/helper/input.go | 16 ++-- operator/helper/input_test.go | 6 +- operator/helper/labeler.go | 74 ------------------- plugin/parameter.go | 2 +- 53 files changed, 454 insertions(+), 415 deletions(-) create mode 100644 entry/attribute_field.go rename entry/{label_field_test.go => attribute_field_test.go} (73%) delete mode 100644 entry/label_field.go create mode 100644 internal/tools/.vscode/settings.json create mode 100644 operator/helper/attributer.go rename operator/helper/{labeler_test.go => attributer_test.go} (69%) delete mode 100644 operator/helper/labeler.go diff --git a/CHANGELOG.md b/CHANGELOG.md index edc07468..e73ba960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -182,8 +182,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `Tags` field was removed from Entry ([PR95](https://github.com/observIQ/stanza/pull/95)) ### Changed -- The `host_metadata` operator now writes to an entry's `Resource` field, instead of Labels -- The `host_labeler` helper has been renamed `host_identifier` +- The `host_metadata` operator now writes to an entry's `Resource` field, instead of Attributes +- The `host_attributer` helper has been renamed `host_identifier` - The `metadata` operator embeds the `Identifier` helper and supports writing to `Resource` - Input operators embed the `Identifier` helper and support writing to `Resource` - The `k8s_event` operator now supports the `write_to`, `labels`, and `resource` configuration options diff --git a/docs/operators/file_input.md b/docs/operators/file_input.md index e8a88a86..8ccf3d2e 100644 --- a/docs/operators/file_input.md +++ b/docs/operators/file_input.md @@ -20,8 +20,8 @@ The `file_input` operator reads logs from files. It will place the lines read in | `fingerprint_size` | `1kb` | The number of bytes with which to identify a file. The first bytes in the file are used as the fingerprint. Decreasing this value at any point will cause existing fingerprints to forgotten, meaning that all files will be read from the beginning (one time). | | `max_log_size` | `1MiB` | The maximum size of a log entry to read before failing. Protects against reading large amounts of data into memory | | `max_concurrent_files` | 1024 | The maximum number of log files from which logs will be read concurrently. If the number of files matched in the `include` pattern exceeds this number, then files will be processed in batches. One batch will be processed per `poll_interval`. | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | Note that by default, no logs will be read unless the monitored file is actively being written to because `start_at` defaults to `end`. diff --git a/docs/operators/filter.md b/docs/operators/filter.md index 492a26af..a0981e53 100644 --- a/docs/operators/filter.md +++ b/docs/operators/filter.md @@ -25,7 +25,7 @@ The `filter` operator filters incoming entries that match an expression. ```yaml - type: filter - expr: '$labels.env == "production"' + expr: '$attributes.env == "production"' output: my_output ``` diff --git a/docs/operators/host_metadata.md b/docs/operators/host_metadata.md index 5658bb5e..942839b3 100644 --- a/docs/operators/host_metadata.md +++ b/docs/operators/host_metadata.md @@ -15,7 +15,7 @@ The `host_metadata` operator adds hostname and ip to the resource of incoming en ### Example Configurations -#### Add static tags and labels +#### Add static attributes Configuration: ```yaml diff --git a/docs/operators/journald_input.md b/docs/operators/journald_input.md index 1714e6f3..038d6643 100644 --- a/docs/operators/journald_input.md +++ b/docs/operators/journald_input.md @@ -16,8 +16,8 @@ The `journald_input` operator will use the `__REALTIME_TIMESTAMP` field of the j | `files` | | A list of journal files to read entries from | | `write_to` | $ | The record [field](/docs/types/field.md) written to when creating a new log entry | | `start_at` | `end` | At startup, where to start reading logs from the file. Options are `beginning` or `end` | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | ### Example Configurations diff --git a/docs/operators/k8s_event_input.md b/docs/operators/k8s_event_input.md index 92f738f5..8e197c17 100644 --- a/docs/operators/k8s_event_input.md +++ b/docs/operators/k8s_event_input.md @@ -13,8 +13,8 @@ Kubernetes API, and currently requires that Stanza is running inside a Kubernete | `discover_namespaces` | `true` | If true, the operator will regularly poll for new namespaces to include | | `discovery_interval ` | `1m` | The interval at which the operator searches for new namespaces to follow | | `write_to` | $ | The record [field](/docs/types/field.md) written to when creating a new log entry | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | ### Example Configurations @@ -30,7 +30,7 @@ Output events: { "timestamp": "2020-08-13T17:41:44.581552468Z", "severity": 0, - "labels": { + "attributes": { "event_type": "ADDED" }, "record": { diff --git a/docs/operators/k8s_metadata_decorator.md b/docs/operators/k8s_metadata_decorator.md index 6a543e88..df80cc20 100644 --- a/docs/operators/k8s_metadata_decorator.md +++ b/docs/operators/k8s_metadata_decorator.md @@ -1,6 +1,6 @@ ## `k8s_metadata_decorator` operator -The `k8s_metadata_decorator` operator adds labels and annotations to the entry using data from the Kubernetes metadata API. +The `k8s_metadata_decorator` operator adds attributes to the entry using data from the Kubernetes metadata API. ### Configuration Fields @@ -18,7 +18,7 @@ The `k8s_metadata_decorator` operator adds labels and annotations to the entry u ### Example Configurations -#### Add labels and annotations to a log entry +#### Add attributes to a log entry Configuration: ```yaml @@ -46,7 +46,7 @@ Configuration: ```json { "timestamp": "", - "labels": { + "attributes": { "k8s_ns_annotation/addonmanager.kubernetes.io/mode": "Reconcile", "k8s_ns_annotation/control-plane": "true", "k8s_ns_annotation/kubernetes.io/cluster-service": "true", diff --git a/docs/operators/metadata.md b/docs/operators/metadata.md index bcf8f614..19fb3dac 100644 --- a/docs/operators/metadata.md +++ b/docs/operators/metadata.md @@ -1,30 +1,30 @@ ## `metadata` operator -The `metadata` operator adds labels to incoming entries. +The `metadata` operator adds attributes to incoming entries. ### Configuration Fields -| Field | Default | Description | -| --- | --- | --- | -| `id` | `metadata` | A unique identifier for the operator | -| `output` | Next in pipeline | The connected operator(s) that will receive all outbound entries | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | -| `on_error` | `send` | The behavior of the operator if it encounters an error. See [on_error](/docs/types/on_error.md) | +| Field | Default | Description | +| --- | --- | --- | +| `id` | `metadata` | A unique identifier for the operator | +| `output` | Next in pipeline | The connected operator(s) that will receive all outbound entries | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | +| `on_error` | `send` | The behavior of the operator if it encounters an error. See [on_error](/docs/types/on_error.md) | Inside the label values, an [expression](/docs/types/expression.md) surrounded by `EXPR()` will be replaced with the evaluated form of the expression. The entry's record can be accessed -with the `$` variable in the expression so labels can be added dynamically from fields. +with the `$` variable in the expression so attributes can be added dynamically from fields. ### Example Configurations -#### Add static labels and resource +#### Add static attributes and resource Configuration: ```yaml - type: metadata - labels: + attributes: environment: "production" resource: cluster: "blue" @@ -38,7 +38,7 @@ Configuration: ```json { "timestamp": "2020-06-15T11:15:50.475364-04:00", - "labels": {}, + "attributes": {}, "record": { "message": "test" } @@ -51,7 +51,7 @@ Configuration: ```json { "timestamp": "2020-06-15T11:15:50.475364-04:00", - "labels": { + "attributes": { "environment": "production" }, "resource": { @@ -67,13 +67,13 @@ Configuration: -#### Add dynamic tags and labels +#### Add dynamic tags and attributes Configuration: ```yaml - type: metadata output: metadata_receiver - labels: + attributes: environment: 'EXPR( $.environment == "production" ? "prod" : "dev" )' ``` @@ -85,7 +85,7 @@ Configuration: ```json { "timestamp": "2020-06-15T11:15:50.475364-04:00", - "labels": {}, + "attributes": {}, "record": { "production_location": "us_east", "environment": "nonproduction" @@ -99,7 +99,7 @@ Configuration: ```json { "timestamp": "2020-06-15T11:15:50.475364-04:00", - "labels": { + "attributes": { "environment": "dev" }, "record": { diff --git a/docs/operators/router.md b/docs/operators/router.md index 76bf8898..348ae0df 100644 --- a/docs/operators/router.md +++ b/docs/operators/router.md @@ -18,11 +18,11 @@ An entry that does not match any of the routes is dropped and not processed furt #### Route configuration -| Field | Default | Description | -| --- | --- | --- | -| `output` | required | The connected operator(s) that will receive all outbound entries for this route | -| `expr` | required | An [expression](/docs/types/expression.md) that returns a boolean. The record of the routed entry is available as `$` | -| `labels` | {} | A map of `key: value` labels to add to an entry that matches the route | +| Field | Default | Description | +| --- | --- | --- | +| `output` | required | The connected operator(s) that will receive all outbound entries for this route | +| `expr` | required | An [expression](/docs/types/expression.md) that returns a boolean. The record of the routed entry is available as `$` | +| `attributes` | {} | A map of `key: value` pairs to add to an entry that matches the route | ### Examples diff --git a/docs/operators/syslog_input.md b/docs/operators/syslog_input.md index 9b0b022c..efebc8a4 100644 --- a/docs/operators/syslog_input.md +++ b/docs/operators/syslog_input.md @@ -4,15 +4,15 @@ The `syslog_input` operator listens for syslog format logs from UDP/TCP packages ### Configuration Fields -| Field | Default | Description | -| ---------- | ---------------- | ------------------------------------------------------------ | -| `id` | `syslog_input` | A unique identifier for the operator | -| `output` | Next in pipeline | The connected operator(s) that will receive all outbound entries | -| `tcp` | {} | A [tcp_input config](./tcp_input.md#configuration-fields) to defined syslog_parser operator. | -| `udp` | {} | A [udp_input config](./udp_input.md#configuration-fields) to defined syslog_parser operator. | -| `syslog` | required | A [syslog parser config](./syslog_parser.md#configuration-fields) to defined syslog_parser operator. | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| Field | Default | Description | +| ---------- | ---------------- | ------------------------------------------------------------ | +| `id` | `syslog_input` | A unique identifier for the operator | +| `output` | Next in pipeline | The connected operator(s) that will receive all outbound entries | +| `tcp` | {} | A [tcp_input config](./tcp_input.md#configuration-fields) to defined syslog_parser operator. | +| `udp` | {} | A [udp_input config](./udp_input.md#configuration-fields) to defined syslog_parser operator. | +| `syslog` | required | A [syslog parser config](./syslog_parser.md#configuration-fields) to defined syslog_parser operator. | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | diff --git a/docs/operators/tcp_input.md b/docs/operators/tcp_input.md index aba939c2..9526f1cd 100644 --- a/docs/operators/tcp_input.md +++ b/docs/operators/tcp_input.md @@ -12,8 +12,8 @@ The `tcp_input` operator listens for logs on one or more TCP connections. The op | `listen_address` | required | A listen address of the form `:` | | `tls` | | An optional `TLS` configuration (see the TLS configuration section) | | `write_to` | $ | The record [field](/docs/types/field.md) written to when creating a new log entry | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | #### TLS Configuration diff --git a/docs/operators/udp_input.md b/docs/operators/udp_input.md index 7b80f340..961caac4 100644 --- a/docs/operators/udp_input.md +++ b/docs/operators/udp_input.md @@ -10,8 +10,8 @@ The `udp_input` operator listens for logs from UDP packets. | `output` | Next in pipeline | The connected operator(s) that will receive all outbound entries | | `listen_address` | required | A listen address of the form `:` | | `write_to` | $ | The record [field](/docs/types/field.md) written to when creating a new log entry | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | ### Example Configurations diff --git a/docs/operators/windows_eventlog_input.md b/docs/operators/windows_eventlog_input.md index 4be7ac07..51edc251 100644 --- a/docs/operators/windows_eventlog_input.md +++ b/docs/operators/windows_eventlog_input.md @@ -13,8 +13,8 @@ The `windows_eventlog_input` operator reads logs from the windows event log API. | `start_at` | `end` | On first startup, where to start reading logs from the API. Options are `beginning` or `end` | | `poll_interval` | 1s | The interval at which the channel is checked for new log entries. This check begins again after all new records have been read | | `write_to` | $ | The record [field](/docs/types/field.md) written to when creating a new log entry | -| `labels` | {} | A map of `key: value` labels to add to the entry's labels | -| `resource` | {} | A map of `key: value` labels to add to the entry's resource | +| `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes | +| `resource` | {} | A map of `key: value` pairs to add to the entry's resource | ### Example Configurations diff --git a/docs/types/entry.md b/docs/types/entry.md index dfedcb4c..b7374400 100644 --- a/docs/types/entry.md +++ b/docs/types/entry.md @@ -9,7 +9,7 @@ Entry is the base representation of log data as it moves through a pipeline. All | `severity` | The [severity](/docs/types/field.md) of the log. | | `severity_text` | The original text that was interpreted as a [severity](/docs/types/field.md). | | `resource` | A map of key/value pairs that describe the resource from which the log originated. | -| `labels` | A map of key/value pairs that provide additional context to the log. This value is often used by a consumer to filter logs. | +| `attributes` | A map of key/value pairs that provide additional context to the log. This value is often used by a consumer to filter logs. | | `record` | The contents of the log. This value is often modified and restructured in the pipeline. It may be a string, number, or object. | @@ -20,7 +20,7 @@ Represented in `json` format, an entry may look like the following: "resource": { "uuid": "11112222-3333-4444-5555-666677778888", }, - "labels": { + "attributes": { "env": "prod", }, "record": { diff --git a/docs/types/expression.md b/docs/types/expression.md index 65f39b34..3371db50 100644 --- a/docs/types/expression.md +++ b/docs/types/expression.md @@ -8,7 +8,7 @@ For reference documentation of the expression language, see [here](https://githu Available to the expressions are a few special variables: - `$record` contains the entry's record -- `$labels` contains the entry's labels +- `$attributes` contains the entry's attributes - `$resource` contains the entry's resource - `$timestamp` contains the entry's timestamp - `env()` is a function that allows you to read environment variables @@ -19,6 +19,6 @@ Available to the expressions are a few special variables: ```yaml - type: metadata - labels: + attributes: stack: 'EXPR(env("STACK"))' ``` diff --git a/docs/types/field.md b/docs/types/field.md index 689c2849..d4ef35a1 100644 --- a/docs/types/field.md +++ b/docs/types/field.md @@ -4,9 +4,9 @@ A _Field_ is a reference to a value in a log [entry](/docs/types/field.md). Many [operators](/docs/operators/README.md) use fields in their configurations. For example, parsers use fields to specify which value to parse and where to write a new value. -Fields are `.`-delimited strings which allow you to select labels or records on the entry. +Fields are `.`-delimited strings which allow you to select attributes or records on the entry. -Fields can be used to select record, resource, or label values. For values on the record, use the prefix `$record` such as `$record.my_value`. To select a label, prefix your field with `$label` such as with `$label.my_label`. For resource values, use the prefix `$resource`. +Fields can be used to select record, resource, or label values. For values on the record, use the prefix `$record` such as `$record.my_value`. To select a label, prefix your field with `$label` such as with `$label.my_attribute`. For resource values, use the prefix `$resource`. If a field contains a dot in it, a field can alternatively use bracket syntax for traversing through a map. For example, to select the key `k8s.cluster.name` on the entry's record, you can use the field `$record["k8s.cluster.name"]`. @@ -27,8 +27,8 @@ Config: value: "value3" - remove: "$record.key2.nested_key1" - add: - field: "$labels.my_label" - value: "my_label_value" + field: "$attributes.my_attribute" + value: "my_attribute_value" ``` @@ -39,7 +39,7 @@ Config: ```json { "timestamp": "", - "labels": {}, + "attributes": {}, "record": { "key1": "value1", "key2": { @@ -56,8 +56,8 @@ Config: ```json { "timestamp": "", - "labels": { - "my_label": "my_label_value" + "attributes": { + "my_attribute": "my_attribute_value" }, "record": { "key1": "value1", @@ -83,7 +83,7 @@ Given the following entry, we can use fields as follows: "resource": { "uuid": "11112222-3333-4444-5555-666677778888", }, - "labels": { + "attributes": { "env": "prod", }, "record": { @@ -101,5 +101,5 @@ Given the following entry, we can use fields as follows: | $record.message | `"Something happened."` | | message | `"Something happened."` | | $record.details.count | `100` | -| $labels.env | `"prod"` | +| $attributes.env | `"prod"` | | $resource.uuid | `"11112222-3333-4444-5555-666677778888"` | diff --git a/entry/attribute_field.go b/entry/attribute_field.go new file mode 100644 index 00000000..f45debd7 --- /dev/null +++ b/entry/attribute_field.go @@ -0,0 +1,71 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package entry + +import ( + "fmt" + "strings" +) + +// AttributeField is the path to an entry attribute +type AttributeField struct { + key string +} + +// Get will return the attribute value and a boolean indicating if it exists +func (l AttributeField) Get(entry *Entry) (interface{}, bool) { + if entry.Attributes == nil { + return "", false + } + val, ok := entry.Attributes[l.key] + return val, ok +} + +// Set will set the attribute value on an entry +func (l AttributeField) Set(entry *Entry, val interface{}) error { + if entry.Attributes == nil { + entry.Attributes = make(map[string]string, 1) + } + + str, ok := val.(string) + if !ok { + return fmt.Errorf("cannot set a attribute to a non-string value") + } + entry.Attributes[l.key] = str + return nil +} + +// Delete will delete a attribute from an entry +func (l AttributeField) Delete(entry *Entry) (interface{}, bool) { + if entry.Attributes == nil { + return "", false + } + + val, ok := entry.Attributes[l.key] + delete(entry.Attributes, l.key) + return val, ok +} + +func (l AttributeField) String() string { + if strings.Contains(l.key, ".") { + return fmt.Sprintf(`$attributes['%s']`, l.key) + } + return "$attributes." + l.key +} + +// NewAttributeField will creat a new attribute field from a key +func NewAttributeField(key string) Field { + return Field{AttributeField{key}} +} diff --git a/entry/label_field_test.go b/entry/attribute_field_test.go similarity index 73% rename from entry/label_field_test.go rename to entry/attribute_field_test.go index 23e6781c..de3f3e8f 100644 --- a/entry/label_field_test.go +++ b/entry/attribute_field_test.go @@ -20,10 +20,10 @@ import ( "github.com/stretchr/testify/require" ) -func TestLabelFieldGet(t *testing.T) { +func TestAttributeFieldGet(t *testing.T) { cases := []struct { name string - labels map[string]string + attributes map[string]string field Field expected interface{} expectedOK bool @@ -33,7 +33,7 @@ func TestLabelFieldGet(t *testing.T) { map[string]string{ "test": "val", }, - NewLabelField("test"), + NewAttributeField("test"), "val", true, }, @@ -42,14 +42,14 @@ func TestLabelFieldGet(t *testing.T) { map[string]string{ "test": "val", }, - NewLabelField("nonexistent"), + NewAttributeField("nonexistent"), "", false, }, { "NilMap", nil, - NewLabelField("nonexistent"), + NewAttributeField("nonexistent"), "", false, }, @@ -58,7 +58,7 @@ func TestLabelFieldGet(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { entry := New() - entry.Labels = tc.labels + entry.Attributes = tc.attributes val, ok := entry.Get(tc.field) require.Equal(t, tc.expectedOK, ok) require.Equal(t, tc.expected, val) @@ -66,21 +66,21 @@ func TestLabelFieldGet(t *testing.T) { } } -func TestLabelFieldDelete(t *testing.T) { +func TestAttributeFieldDelete(t *testing.T) { cases := []struct { - name string - labels map[string]string - field Field - expected interface{} - expectedOK bool - expectedLabels map[string]string + name string + attributes map[string]string + field Field + expected interface{} + expectedOK bool + expectedAttributes map[string]string }{ { "Simple", map[string]string{ "test": "val", }, - NewLabelField("test"), + NewAttributeField("test"), "val", true, map[string]string{}, @@ -90,7 +90,7 @@ func TestLabelFieldDelete(t *testing.T) { map[string]string{ "test": "val", }, - NewLabelField("nonexistent"), + NewAttributeField("nonexistent"), "", false, map[string]string{ @@ -100,7 +100,7 @@ func TestLabelFieldDelete(t *testing.T) { { "NilMap", nil, - NewLabelField("nonexistent"), + NewAttributeField("nonexistent"), "", false, nil, @@ -110,7 +110,7 @@ func TestLabelFieldDelete(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { entry := New() - entry.Labels = tc.labels + entry.Attributes = tc.attributes val, ok := entry.Delete(tc.field) require.Equal(t, tc.expectedOK, ok) require.Equal(t, tc.expected, val) @@ -118,10 +118,10 @@ func TestLabelFieldDelete(t *testing.T) { } } -func TestLabelFieldSet(t *testing.T) { +func TestAttributeFieldSet(t *testing.T) { cases := []struct { name string - labels map[string]string + attributes map[string]string field Field val interface{} expected map[string]string @@ -130,7 +130,7 @@ func TestLabelFieldSet(t *testing.T) { { "Simple", map[string]string{}, - NewLabelField("test"), + NewAttributeField("test"), "val", map[string]string{ "test": "val", @@ -142,7 +142,7 @@ func TestLabelFieldSet(t *testing.T) { map[string]string{ "test": "original", }, - NewLabelField("test"), + NewAttributeField("test"), "val", map[string]string{ "test": "val", @@ -152,7 +152,7 @@ func TestLabelFieldSet(t *testing.T) { { "NilMap", nil, - NewLabelField("test"), + NewAttributeField("test"), "val", map[string]string{ "test": "val", @@ -162,7 +162,7 @@ func TestLabelFieldSet(t *testing.T) { { "NonString", map[string]string{}, - NewLabelField("test"), + NewAttributeField("test"), 123, map[string]string{ "test": "val", @@ -174,33 +174,33 @@ func TestLabelFieldSet(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { entry := New() - entry.Labels = tc.labels + entry.Attributes = tc.attributes err := entry.Set(tc.field, tc.val) if tc.expectedErr { require.Error(t, err) return } - require.Equal(t, tc.expected, entry.Labels) + require.Equal(t, tc.expected, entry.Attributes) }) } } -func TestLabelFieldString(t *testing.T) { +func TestAttributeFieldString(t *testing.T) { cases := []struct { name string - field LabelField + field AttributeField expected string }{ { "Simple", - LabelField{"foo"}, - "$labels.foo", + AttributeField{"foo"}, + "$attributes.foo", }, { "Empty", - LabelField{""}, - "$labels.", + AttributeField{""}, + "$attributes.", }, } diff --git a/entry/entry.go b/entry/entry.go index 3db86028..7f4d9849 100644 --- a/entry/entry.go +++ b/entry/entry.go @@ -45,7 +45,7 @@ type Entry struct { Timestamp time.Time `json:"timestamp" yaml:"timestamp"` Severity Severity `json:"severity" yaml:"severity"` SeverityText string `json:"severity_text,omitempty" yaml:"severity_text,omitempty"` - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"` Resource map[string]string `json:"resource,omitempty" yaml:"resource,omitempty"` Record interface{} `json:"record" yaml:"record"` } @@ -57,12 +57,12 @@ func New() *Entry { } } -// AddLabel will add a key/value pair to the entry's labels. -func (entry *Entry) AddLabel(key, value string) { - if entry.Labels == nil { - entry.Labels = make(map[string]string) +// AddAttribute will add a key/value pair to the entry's attributes. +func (entry *Entry) AddAttribute(key, value string) { + if entry.Attributes == nil { + entry.Attributes = make(map[string]string) } - entry.Labels[key] = value + entry.Attributes[key] = value } // AddResourceKey wil add a key/value pair to the entry's resource. @@ -193,7 +193,7 @@ func (entry *Entry) Copy() *Entry { Timestamp: entry.Timestamp, Severity: entry.Severity, SeverityText: entry.SeverityText, - Labels: copyStringMap(entry.Labels), + Attributes: copyStringMap(entry.Attributes), Resource: copyStringMap(entry.Resource), Record: copyValue(entry.Record), } diff --git a/entry/entry_test.go b/entry/entry_test.go index f09294a7..21a15a80 100644 --- a/entry/entry_test.go +++ b/entry/entry_test.go @@ -139,7 +139,7 @@ func TestCopy(t *testing.T) { entry.SeverityText = "ok" entry.Timestamp = time.Time{} entry.Record = "test" - entry.Labels = map[string]string{"label": "value"} + entry.Attributes = map[string]string{"label": "value"} entry.Resource = map[string]string{"resource": "value"} copy := entry.Copy() @@ -147,13 +147,13 @@ func TestCopy(t *testing.T) { entry.SeverityText = "1" entry.Timestamp = time.Now() entry.Record = "new" - entry.Labels = map[string]string{"label": "new value"} + entry.Attributes = map[string]string{"label": "new value"} entry.Resource = map[string]string{"resource": "new value"} require.Equal(t, time.Time{}, copy.Timestamp) require.Equal(t, Severity(0), copy.Severity) require.Equal(t, "ok", copy.SeverityText) - require.Equal(t, map[string]string{"label": "value"}, copy.Labels) + require.Equal(t, map[string]string{"label": "value"}, copy.Attributes) require.Equal(t, map[string]string{"resource": "value"}, copy.Resource) require.Equal(t, "test", copy.Record) } @@ -184,14 +184,14 @@ func TestFieldFromString(t *testing.T) { false, }, { - "SimpleLabel", - "$labels.test", - Field{LabelField{"test"}}, + "SimpleAttribute", + "$attributes.test", + Field{AttributeField{"test"}}, false, }, { - "LabelsTooManyFields", - "$labels.test.bar", + "AttributesTooManyFields", + "$attributes.test.bar", Field{}, true, }, @@ -210,11 +210,11 @@ func TestFieldFromString(t *testing.T) { } } -func TestAddLabel(t *testing.T) { +func TestAddAttribute(t *testing.T) { entry := Entry{} - entry.AddLabel("label", "value") + entry.AddAttribute("label", "value") expected := map[string]string{"label": "value"} - require.Equal(t, expected, entry.Labels) + require.Equal(t, expected, entry.Attributes) } func TestAddResourceKey(t *testing.T) { @@ -226,7 +226,7 @@ func TestAddResourceKey(t *testing.T) { func TestReadToInterfaceMapWithMissingField(t *testing.T) { entry := Entry{} - field := NewLabelField("label") + field := NewAttributeField("label") dest := map[string]interface{}{} err := entry.readToInterfaceMap(field, &dest) require.Error(t, err) @@ -235,7 +235,7 @@ func TestReadToInterfaceMapWithMissingField(t *testing.T) { func TestReadToStringMapWithMissingField(t *testing.T) { entry := Entry{} - field := NewLabelField("label") + field := NewAttributeField("label") dest := map[string]string{} err := entry.readToStringMap(field, &dest) require.Error(t, err) @@ -244,7 +244,7 @@ func TestReadToStringMapWithMissingField(t *testing.T) { func TestReadToInterfaceMissingField(t *testing.T) { entry := Entry{} - field := NewLabelField("label") + field := NewAttributeField("label") var dest interface{} err := entry.readToInterface(field, &dest) require.Error(t, err) diff --git a/entry/field.go b/entry/field.go index 5875efbb..887ec161 100644 --- a/entry/field.go +++ b/entry/field.go @@ -20,9 +20,9 @@ import ( ) const ( - labelsPrefix = "$labels" - resourcePrefix = "$resource" - recordPrefix = "$record" + attributesPrefix = "$attributes" + resourcePrefix = "$resource" + recordPrefix = "$record" ) // Field represents a potential field on an entry. @@ -69,11 +69,11 @@ func fieldFromString(s string) (Field, error) { } switch split[0] { - case labelsPrefix: + case attributesPrefix: if len(split) != 2 { - return Field{}, fmt.Errorf("labels cannot be nested") + return Field{}, fmt.Errorf("attributes cannot be nested") } - return Field{LabelField{split[1]}}, nil + return Field{AttributeField{split[1]}}, nil case resourcePrefix: if len(split) != 2 { return Field{}, fmt.Errorf("resource fields cannot be nested") diff --git a/entry/field_test.go b/entry/field_test.go index c5679144..5be20396 100644 --- a/entry/field_test.go +++ b/entry/field_test.go @@ -181,14 +181,14 @@ func TestFieldMarshalYAML(t *testing.T) { "$record['test1']['test.2']\n", }, { - "LabelField", - NewLabelField("test1"), - "$labels.test1\n", + "AttributeField", + NewAttributeField("test1"), + "$attributes.test1\n", }, { - "LabelFieldWithDots", - NewLabelField("test.1"), - "$labels['test.1']\n", + "AttributeFieldWithDots", + NewAttributeField("test.1"), + "$attributes['test.1']\n", }, { "ResourceField", diff --git a/entry/label_field.go b/entry/label_field.go deleted file mode 100644 index c3c271a8..00000000 --- a/entry/label_field.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package entry - -import ( - "fmt" - "strings" -) - -// LabelField is the path to an entry label -type LabelField struct { - key string -} - -// Get will return the label value and a boolean indicating if it exists -func (l LabelField) Get(entry *Entry) (interface{}, bool) { - if entry.Labels == nil { - return "", false - } - val, ok := entry.Labels[l.key] - return val, ok -} - -// Set will set the label value on an entry -func (l LabelField) Set(entry *Entry, val interface{}) error { - if entry.Labels == nil { - entry.Labels = make(map[string]string, 1) - } - - str, ok := val.(string) - if !ok { - return fmt.Errorf("cannot set a label to a non-string value") - } - entry.Labels[l.key] = str - return nil -} - -// Delete will delete a label from an entry -func (l LabelField) Delete(entry *Entry) (interface{}, bool) { - if entry.Labels == nil { - return "", false - } - - val, ok := entry.Labels[l.key] - delete(entry.Labels, l.key) - return val, ok -} - -func (l LabelField) String() string { - if strings.Contains(l.key, ".") { - return fmt.Sprintf(`$labels['%s']`, l.key) - } - return "$labels." + l.key -} - -// NewLabelField will creat a new label field from a key -func NewLabelField(key string) Field { - return Field{LabelField{key}} -} diff --git a/examples/tomcat/config.yaml b/examples/tomcat/config.yaml index 1ff45dad..0c2e56cc 100644 --- a/examples/tomcat/config.yaml +++ b/examples/tomcat/config.yaml @@ -8,7 +8,7 @@ pipeline: start_at: beginning include: - ./access.log - labels: + attributes: log_type: tomcat # Parse the logs into labeled fields diff --git a/internal/tools/.vscode/settings.json b/internal/tools/.vscode/settings.json new file mode 100644 index 00000000..a4606455 --- /dev/null +++ b/internal/tools/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "go.inferGopath": false +} \ No newline at end of file diff --git a/internal/tools/go.mod b/internal/tools/go.mod index b62988ac..1e3f97ae 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -3,7 +3,7 @@ module github.com/open-telemetry/opentelemetry-log-collection/internal/tools go 1.15 require ( - github.com/golangci/golangci-lint v1.38.0 // indirect - github.com/google/addlicense v0.0.0-20200906110928-a0294312aa76 // indirect - github.com/vektra/mockery v1.1.2 // indirect + github.com/golangci/golangci-lint v1.38.0 + github.com/google/addlicense v0.0.0-20200906110928-a0294312aa76 + github.com/tcnksm/ghr v0.13.0 ) diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 7c9fa20d..653ed8ef 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -23,6 +23,8 @@ github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/Songmu/retry v0.1.0 h1:hPA5xybQsksLR/ry/+t/7cFajPW+dqjmjhzZhioBILA= +github.com/Songmu/retry v0.1.0/go.mod h1:7sXIW7eseB9fq0FUvigRcQMVLR9tuHI0Scok+rkpAuA= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -98,6 +100,7 @@ github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUP github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= @@ -125,6 +128,7 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= @@ -158,6 +162,10 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -166,6 +174,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.3.6/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254 h1:Nb2aRlC404yz7gQIfRZxX9/MLvQiqXyiBTJtgAy6yrI= github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw= @@ -197,6 +206,8 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -207,6 +218,7 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jgautheron/goconst v1.4.0 h1:hp9XKUpe/MPyDamUbfsrGpe+3dnY2whNK4EtB86dvLM= github.com/jgautheron/goconst v1.4.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= @@ -218,6 +230,7 @@ github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhB github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julz/importas v0.0.0-20210226073942-60b4fa260dd0 h1:exZBMUS/kB/AhxSj/9lIIxhqkCpXXdKScjFWQUTbi3M= @@ -235,6 +248,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 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/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.4.0 h1:2Nx7XbdbE/BYZeoip2mURKUdtHQRuy6Ug+wR7K9ywNM= github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= @@ -245,6 +259,7 @@ github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+s github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -253,10 +268,12 @@ github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpAp github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= @@ -274,6 +291,8 @@ github.com/mgechev/revive v1.0.3 h1:z3FL6IFFN3JKzHYHD8O1ExH9g/4lAGJ5x1+9rPZgsFg= github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -294,20 +313,25 @@ github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaP github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= github.com/nbutton23/zxcvbn-go v0.0.0-20201221231540-e56b841a3c88 h1:o+O3Cd1HO9CTgxE3/C8p5I5Y4C0yYWbF8d4IkfOLtcQ= github.com/nbutton23/zxcvbn-go v0.0.0-20201221231540-e56b841a3c88/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U= github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -365,7 +389,9 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= @@ -402,6 +428,12 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tcnksm/ghr v0.13.0 h1:a5ZbaUAfiaiw6rEDJVUEDYA9YreZOkh3XAfXHWn8zu8= +github.com/tcnksm/ghr v0.13.0/go.mod h1:tcp6tzbRYE0LqFSG7ykXP/BVG1/2BkX6aIn9FFV1mIQ= +github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= +github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= +github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= +github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tetafro/godot v1.4.4 h1:VAtLEoAMmopIzHVWVBrztjVWDeYm1OD/DKqhqXR4828= @@ -423,8 +455,6 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vektra/mockery v1.1.2 h1:uc0Yn67rJpjt8U/mAZimdCKn9AeA97BOkjpmtBSlfP4= -github.com/vektra/mockery v1.1.2/go.mod h1:VcfZjKaFOPO+MpN4ZvwPjs4c48lkq1o3Ym8yHZJu0jU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -487,9 +517,12 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -565,7 +598,6 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200323144430-8dcfad9e016e/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -604,6 +636,7 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -622,17 +655,20 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/tools/tools.go b/internal/tools/tools.go index 71c50bc1..b7706c3b 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -25,4 +25,4 @@ import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/google/addlicense" _ "github.com/tcnksm/ghr" -) \ No newline at end of file +) diff --git a/operator/builtin/input/file/config.go b/operator/builtin/input/file/config.go index 9a84a2b8..25654881 100644 --- a/operator/builtin/input/file/config.go +++ b/operator/builtin/input/file/config.go @@ -140,12 +140,12 @@ func (c InputConfig) Build(context operator.BuildContext) ([]operator.Operator, fileNameField := entry.NewNilField() if c.IncludeFileName { - fileNameField = entry.NewLabelField("file_name") + fileNameField = entry.NewAttributeField("file_name") } filePathField := entry.NewNilField() if c.IncludeFilePath { - filePathField = entry.NewLabelField("file_path") + filePathField = entry.NewAttributeField("file_path") } op := &InputOperator{ diff --git a/operator/builtin/input/file/config_test.go b/operator/builtin/input/file/config_test.go index d914f8e8..36130e98 100644 --- a/operator/builtin/input/file/config_test.go +++ b/operator/builtin/input/file/config_test.go @@ -277,13 +277,11 @@ func TestMapStructureDecodeConfigWithHook(t *testing.T) { expect := NewTestInputConfig() input := map[string]interface{}{ // InputConfig - "id": "config_test", - "type": "file_input", - "write_to": "$", - "labels": map[string]interface{}{ - }, - "resource": map[string]interface{}{ - }, + "id": "config_test", + "type": "file_input", + "write_to": "$", + "attributes": map[string]interface{}{}, + "resource": map[string]interface{}{}, "include": expect.Include, "exclude": expect.Exclude, @@ -314,15 +312,13 @@ func TestMapStructureDecodeConfig(t *testing.T) { expect := NewTestInputConfig() input := map[string]interface{}{ // InputConfig - "id": "config_test", - "type": "file_input", - "write_to": entry.NewRecordField([]string{}...), - "labels": map[string]interface{}{ - }, - "resource": map[string]interface{}{ - }, - "include": expect.Include, - "exclude": expect.Exclude, + "id": "config_test", + "type": "file_input", + "write_to": entry.NewRecordField([]string{}...), + "attributes": map[string]interface{}{}, + "resource": map[string]interface{}{}, + "include": expect.Include, + "exclude": expect.Exclude, "poll_interval": map[string]interface{}{ "Duration": 200 * 1000 * 1000, }, diff --git a/operator/builtin/input/file/file_test.go b/operator/builtin/input/file/file_test.go index f36a39f9..a67bea8f 100644 --- a/operator/builtin/input/file/file_test.go +++ b/operator/builtin/input/file/file_test.go @@ -140,7 +140,7 @@ func TestBuild(t *testing.T) { require.Equal(t, f.OutputOperators[0], fakeOutput) require.Equal(t, f.Include, []string{"/var/log/testpath.*"}) require.Equal(t, f.FilePathField, entry.NewNilField()) - require.Equal(t, f.FileNameField, entry.NewLabelField("file_name")) + require.Equal(t, f.FileNameField, entry.NewAttributeField("file_name")) require.Equal(t, f.PollInterval, 10*time.Millisecond) }, }, @@ -293,8 +293,8 @@ func TestAddFileFields(t *testing.T) { defer operator.Stop() e := waitForOne(t, logReceived) - require.Equal(t, filepath.Base(temp.Name()), e.Labels["file_name"]) - require.Equal(t, temp.Name(), e.Labels["file_path"]) + require.Equal(t, filepath.Base(temp.Name()), e.Attributes["file_name"]) + require.Equal(t, temp.Name(), e.Attributes["file_path"]) } // ReadExistingLogs tests that, when starting from beginning, we diff --git a/operator/builtin/input/k8sevent/go.sum b/operator/builtin/input/k8sevent/go.sum index 1fe3998b..919cc141 100644 --- a/operator/builtin/input/k8sevent/go.sum +++ b/operator/builtin/input/k8sevent/go.sum @@ -137,6 +137,8 @@ github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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= diff --git a/operator/builtin/input/k8sevent/k8s_event.go b/operator/builtin/input/k8sevent/k8s_event.go index 4fc54d6c..22f3226a 100644 --- a/operator/builtin/input/k8sevent/k8s_event.go +++ b/operator/builtin/input/k8sevent/k8s_event.go @@ -289,7 +289,7 @@ func (k *K8sEvents) consumeWatchEvents(ctx context.Context, events <-chan watch. entry.Timestamp = typedEvent.FirstTimestamp.Time } - entry.AddLabel("event_type", string(event.Type)) + entry.AddAttribute("event_type", string(event.Type)) k.populateResource(typedEvent, entry) k.Write(ctx, entry) case <-ctx.Done(): diff --git a/operator/builtin/transformer/filter/filter_test.go b/operator/builtin/transformer/filter/filter_test.go index 922a6843..c33865c2 100644 --- a/operator/builtin/transformer/filter/filter_test.go +++ b/operator/builtin/transformer/filter/filter_test.go @@ -58,26 +58,26 @@ func TestFilterOperator(t *testing.T) { false, }, { - "MatchLabel", + "MatchAttribute", &entry.Entry{ Record: map[string]interface{}{ "message": "test_message", }, - Labels: map[string]string{ + Attributes: map[string]string{ "key": "value", }, }, - `$labels.key == "value"`, + `$attributes.key == "value"`, true, }, { - "NoMatchLabel", + "NoMatchAttribute", &entry.Entry{ Record: map[string]interface{}{ "message": "test_message", }, }, - `$labels.key == "value"`, + `$attributes.key == "value"`, false, }, { diff --git a/operator/builtin/transformer/hostmetadata/host_metadata.go b/operator/builtin/transformer/hostmetadata/host_metadata.go index 8faa7737..036cbaf1 100644 --- a/operator/builtin/transformer/hostmetadata/host_metadata.go +++ b/operator/builtin/transformer/hostmetadata/host_metadata.go @@ -50,7 +50,7 @@ func (c HostMetadataConfig) Build(context operator.BuildContext) ([]operator.Ope hostIdentifier, err := c.HostIdentifierConfig.Build() if err != nil { - return nil, errors.Wrap(err, "failed to build host labeler") + return nil, errors.Wrap(err, "failed to build host attributer") } op := &HostMetadata{ diff --git a/operator/builtin/transformer/k8smetadata/go.sum b/operator/builtin/transformer/k8smetadata/go.sum index fabe19d9..590a7c7f 100644 --- a/operator/builtin/transformer/k8smetadata/go.sum +++ b/operator/builtin/transformer/k8smetadata/go.sum @@ -134,6 +134,8 @@ github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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= diff --git a/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator.go b/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator.go index 709eceab..a3aa715a 100644 --- a/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator.go +++ b/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator.go @@ -100,7 +100,7 @@ type MetadataCacheEntry struct { ClusterName string UID string ExpirationTime time.Time - Labels map[string]string + Attributes map[string]string Annotations map[string]string AdditionalResourceValues map[string]string @@ -243,7 +243,7 @@ func (k *K8sMetadataDecorator) refreshNamespaceMetadata(ctx context.Context, nam ClusterName: namespaceResponse.ClusterName, ExpirationTime: time.Now().Add(k.cacheTTL), UID: string(namespaceResponse.UID), - Labels: namespaceResponse.Labels, + Attributes: namespaceResponse.Labels, Annotations: namespaceResponse.Annotations, } k.namespaceCache.Store(namespace, cacheEntry) @@ -276,7 +276,7 @@ func (k *K8sMetadataDecorator) refreshPodMetadata(ctx context.Context, namespace ClusterName: podResponse.ClusterName, UID: string(podResponse.UID), ExpirationTime: time.Now().Add(k.cacheTTL), - Labels: podResponse.Labels, + Attributes: podResponse.Labels, Annotations: podResponse.Annotations, AdditionalResourceValues: map[string]string{ "k8s.replicaset.name": findNameOfKind(podResponse.OwnerReferences, "ReplicaSet"), @@ -320,16 +320,16 @@ func (k *K8sMetadataDecorator) refreshPodMetadata(ctx context.Context, namespace } func (k *K8sMetadataDecorator) decorateEntryWithNamespaceMetadata(nsMeta MetadataCacheEntry, entry *entry.Entry) { - if entry.Labels == nil { - entry.Labels = make(map[string]string) + if entry.Attributes == nil { + entry.Attributes = make(map[string]string) } for k, v := range nsMeta.Annotations { - entry.Labels["k8s-ns-annotation/"+k] = v + entry.Attributes["k8s-ns-annotation/"+k] = v } - for k, v := range nsMeta.Labels { - entry.Labels["k8s-ns/"+k] = v + for k, v := range nsMeta.Attributes { + entry.Attributes["k8s-ns/"+k] = v } entry.Resource["k8s.namespace.uid"] = nsMeta.UID @@ -339,16 +339,16 @@ func (k *K8sMetadataDecorator) decorateEntryWithNamespaceMetadata(nsMeta Metadat } func (k *K8sMetadataDecorator) decorateEntryWithPodMetadata(podMeta MetadataCacheEntry, entry *entry.Entry) { - if entry.Labels == nil { - entry.Labels = make(map[string]string) + if entry.Attributes == nil { + entry.Attributes = make(map[string]string) } for k, v := range podMeta.Annotations { - entry.Labels["k8s-pod-annotation/"+k] = v + entry.Attributes["k8s-pod-annotation/"+k] = v } - for k, v := range podMeta.Labels { - entry.Labels["k8s-pod/"+k] = v + for k, v := range podMeta.Attributes { + entry.Attributes["k8s-pod/"+k] = v } entry.Resource["k8s.pod.uid"] = podMeta.UID diff --git a/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator_test.go b/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator_test.go index e4966722..340f3fe4 100644 --- a/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator_test.go +++ b/operator/builtin/transformer/k8smetadata/k8s_metadata_decorator_test.go @@ -30,7 +30,7 @@ import ( func TestMetadataCache(t *testing.T) { m := MetadataCache{} entry := MetadataCacheEntry{ - Labels: map[string]string{ + Attributes: map[string]string{ "label1": "value1", }, Annotations: map[string]string{ @@ -93,7 +93,7 @@ func TestK8sMetadataDecoratorCachedMetadata(t *testing.T) { k8s := op.(*K8sMetadataDecorator) k8s.namespaceCache.Store("testnamespace", MetadataCacheEntry{ ExpirationTime: time.Now().Add(time.Hour), - Labels: map[string]string{ + Attributes: map[string]string{ "label1": "lab1", }, ClusterName: "testcluster", @@ -104,7 +104,7 @@ func TestK8sMetadataDecoratorCachedMetadata(t *testing.T) { k8s.podCache.Store("testnamespace:testpodname", MetadataCacheEntry{ ExpirationTime: time.Now().Add(time.Hour), - Labels: map[string]string{ + Attributes: map[string]string{ "podlabel1": "podlab1", }, Annotations: map[string]string{ @@ -116,7 +116,7 @@ func TestK8sMetadataDecoratorCachedMetadata(t *testing.T) { }) expected := entry.Entry{ - Labels: map[string]string{ + Attributes: map[string]string{ "k8s-pod/podlabel1": "podlab1", "k8s-ns/label1": "lab1", "k8s-pod-annotation/podannotation1": "podann1", @@ -132,7 +132,7 @@ func TestK8sMetadataDecoratorCachedMetadata(t *testing.T) { mockOutput.On("Process", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { entry := args.Get(1).(*entry.Entry) - require.Equal(t, expected.Labels, entry.Labels) + require.Equal(t, expected.Attributes, entry.Attributes) require.Equal(t, expected.Resource, entry.Resource) }).Return(nil) diff --git a/operator/builtin/transformer/metadata/metadata.go b/operator/builtin/transformer/metadata/metadata.go index fde2f51c..cb7b2be7 100644 --- a/operator/builtin/transformer/metadata/metadata.go +++ b/operator/builtin/transformer/metadata/metadata.go @@ -31,7 +31,7 @@ func init() { func NewMetadataOperatorConfig(operatorID string) *MetadataOperatorConfig { return &MetadataOperatorConfig{ TransformerConfig: helper.NewTransformerConfig(operatorID, "metadata"), - LabelerConfig: helper.NewLabelerConfig(), + AttributerConfig: helper.NewAttributerConfig(), IdentifierConfig: helper.NewIdentifierConfig(), } } @@ -39,7 +39,7 @@ func NewMetadataOperatorConfig(operatorID string) *MetadataOperatorConfig { // MetadataOperatorConfig is the configuration of a metadata operator type MetadataOperatorConfig struct { helper.TransformerConfig `yaml:",inline"` - helper.LabelerConfig `yaml:",inline"` + helper.AttributerConfig `yaml:",inline"` helper.IdentifierConfig `yaml:",inline"` } @@ -50,9 +50,9 @@ func (c MetadataOperatorConfig) Build(context operator.BuildContext) ([]operator return nil, errors.Wrap(err, "failed to build transformer") } - labeler, err := c.LabelerConfig.Build() + attributer, err := c.AttributerConfig.Build() if err != nil { - return nil, errors.Wrap(err, "failed to build labeler") + return nil, errors.Wrap(err, "failed to build attributer") } identifier, err := c.IdentifierConfig.Build() @@ -62,7 +62,7 @@ func (c MetadataOperatorConfig) Build(context operator.BuildContext) ([]operator metadataOperator := &MetadataOperator{ TransformerOperator: transformerOperator, - Labeler: labeler, + Attributer: attributer, Identifier: identifier, } @@ -72,7 +72,7 @@ func (c MetadataOperatorConfig) Build(context operator.BuildContext) ([]operator // MetadataOperator is an operator that can add metadata to incoming entries type MetadataOperator struct { helper.TransformerOperator - helper.Labeler + helper.Attributer helper.Identifier } @@ -81,10 +81,10 @@ func (p *MetadataOperator) Process(ctx context.Context, entry *entry.Entry) erro return p.ProcessWith(ctx, entry, p.Transform) } -// Transform will transform an entry using the labeler and tagger. +// Transform will transform an entry using the attributer and tagger. func (p *MetadataOperator) Transform(entry *entry.Entry) error { - if err := p.Label(entry); err != nil { - return errors.Wrap(err, "failed to add labels to entry") + if err := p.Attribute(entry); err != nil { + return errors.Wrap(err, "failed to add attributes to entry") } if err := p.Identify(entry); err != nil { diff --git a/operator/builtin/transformer/metadata/metadata_test.go b/operator/builtin/transformer/metadata/metadata_test.go index 10eed7e4..9177135f 100644 --- a/operator/builtin/transformer/metadata/metadata_test.go +++ b/operator/builtin/transformer/metadata/metadata_test.go @@ -38,48 +38,48 @@ func TestMetadata(t *testing.T) { expected *entry.Entry }{ { - "AddLabelLiteral", + "AddAttributeLiteral", func(cfg *MetadataOperatorConfig) { - cfg.Labels = map[string]helper.ExprStringConfig{ + cfg.Attributes = map[string]helper.ExprStringConfig{ "label1": "value1", } }, entry.New(), func() *entry.Entry { e := entry.New() - e.Labels = map[string]string{ + e.Attributes = map[string]string{ "label1": "value1", } return e }(), }, { - "AddLabelExpr", + "AddAttributeExpr", func(cfg *MetadataOperatorConfig) { - cfg.Labels = map[string]helper.ExprStringConfig{ + cfg.Attributes = map[string]helper.ExprStringConfig{ "label1": `EXPR("start" + "end")`, } }, entry.New(), func() *entry.Entry { e := entry.New() - e.Labels = map[string]string{ + e.Attributes = map[string]string{ "label1": "startend", } return e }(), }, { - "AddLabelEnv", + "AddAttributeEnv", func(cfg *MetadataOperatorConfig) { - cfg.Labels = map[string]helper.ExprStringConfig{ + cfg.Attributes = map[string]helper.ExprStringConfig{ "label1": `EXPR(env("TEST_METADATA_PLUGIN_ENV"))`, } }, entry.New(), func() *entry.Entry { e := entry.New() - e.Labels = map[string]string{ + e.Attributes = map[string]string{ "label1": "foo", } return e @@ -153,7 +153,7 @@ func TestMetadata(t *testing.T) { select { case e := <-fake.Received: - require.Equal(t, e.Labels, tc.expected.Labels) + require.Equal(t, e.Attributes, tc.expected.Attributes) require.Equal(t, e.Resource, tc.expected.Resource) case <-time.After(time.Second): require.FailNow(t, "Timed out waiting for entry to be processed") diff --git a/operator/builtin/transformer/noop/noop_test.go b/operator/builtin/transformer/noop/noop_test.go index 279eca7b..6a1f255a 100644 --- a/operator/builtin/transformer/noop/noop_test.go +++ b/operator/builtin/transformer/noop/noop_test.go @@ -63,7 +63,7 @@ func TestProcess(t *testing.T) { op.SetOutputs([]operator.Operator{fake}) entry := entry.New() - entry.AddLabel("label", "value") + entry.AddAttribute("label", "value") entry.AddResourceKey("resource", "value") expected := entry.Copy() diff --git a/operator/builtin/transformer/router/router.go b/operator/builtin/transformer/router/router.go index 50349cf6..673af252 100644 --- a/operator/builtin/transformer/router/router.go +++ b/operator/builtin/transformer/router/router.go @@ -46,9 +46,9 @@ type RouterOperatorConfig struct { // RouterOperatorRouteConfig is the configuration of a route on a router operator type RouterOperatorRouteConfig struct { - helper.LabelerConfig `yaml:",inline"` - Expression string `json:"expr" yaml:"expr"` - OutputIDs helper.OutputIDs `json:"output" yaml:"output"` + helper.AttributerConfig `yaml:",inline"` + Expression string `json:"expr" yaml:"expr"` + OutputIDs helper.OutputIDs `json:"output" yaml:"output"` } // Build will build a router operator from the supplied configuration @@ -73,13 +73,13 @@ func (c RouterOperatorConfig) Build(bc operator.BuildContext) ([]operator.Operat return nil, fmt.Errorf("failed to compile expression '%s': %w", routeConfig.Expression, err) } - labeler, err := routeConfig.LabelerConfig.Build() + attributer, err := routeConfig.AttributerConfig.Build() if err != nil { - return nil, fmt.Errorf("failed to build labeler for route '%s': %w", routeConfig.Expression, err) + return nil, fmt.Errorf("failed to build attributer for route '%s': %w", routeConfig.Expression, err) } route := RouterOperatorRoute{ - Labeler: labeler, + Attributer: attributer, Expression: compiled, OutputIDs: routeConfig.OutputIDs.WithNamespace(bc), } @@ -102,7 +102,7 @@ type RouterOperator struct { // RouterOperatorRoute is a route on a router operator type RouterOperatorRoute struct { - helper.Labeler + helper.Attributer Expression *vm.Program OutputIDs helper.OutputIDs OutputOperators []operator.Operator @@ -127,7 +127,7 @@ func (p *RouterOperator) Process(ctx context.Context, entry *entry.Entry) error // we compile the expression with "AsBool", so this should be safe if matches.(bool) { - if err := route.Label(entry); err != nil { + if err := route.Attribute(entry); err != nil { p.Errorf("Failed to label entry: %s", err) return err } diff --git a/operator/builtin/transformer/router/router_test.go b/operator/builtin/transformer/router/router_test.go index b20cedac..3b98a6fe 100644 --- a/operator/builtin/transformer/router/router_test.go +++ b/operator/builtin/transformer/router/router_test.go @@ -41,19 +41,19 @@ func TestRouterOperator(t *testing.T) { } cases := []struct { - name string - input *entry.Entry - routes []*RouterOperatorRouteConfig - defaultOutput helper.OutputIDs - expectedCounts map[string]int - expectedLabels map[string]string + name string + input *entry.Entry + routes []*RouterOperatorRouteConfig + defaultOutput helper.OutputIDs + expectedCounts map[string]int + expectedAttributes map[string]string }{ { "DefaultRoute", entry.New(), []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), "true", []string{"output1"}, }, @@ -67,7 +67,7 @@ func TestRouterOperator(t *testing.T) { entry.New(), []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `false`, []string{"output1"}, }, @@ -85,12 +85,12 @@ func TestRouterOperator(t *testing.T) { }, []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `$.message == "non_match"`, []string{"output1"}, }, { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `$.message == "test_message"`, []string{"output2"}, }, @@ -100,7 +100,7 @@ func TestRouterOperator(t *testing.T) { nil, }, { - "MatchWithLabel", + "MatchWithAttribute", &entry.Entry{ Record: map[string]interface{}{ "message": "test_message", @@ -108,13 +108,13 @@ func TestRouterOperator(t *testing.T) { }, []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `$.message == "non_match"`, []string{"output1"}, }, { - helper.LabelerConfig{ - Labels: map[string]helper.ExprStringConfig{ + helper.AttributerConfig{ + Attributes: map[string]helper.ExprStringConfig{ "label-key": "label-value", }, }, @@ -137,12 +137,12 @@ func TestRouterOperator(t *testing.T) { }, []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `env("TEST_ROUTER_PLUGIN_ENV") == "foo"`, []string{"output1"}, }, { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `true`, []string{"output2"}, }, @@ -160,7 +160,7 @@ func TestRouterOperator(t *testing.T) { }, []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `false`, []string{"output1"}, }, @@ -178,7 +178,7 @@ func TestRouterOperator(t *testing.T) { }, []*RouterOperatorRouteConfig{ { - helper.NewLabelerConfig(), + helper.NewAttributerConfig(), `true`, []string{"output1"}, }, @@ -201,13 +201,13 @@ func TestRouterOperator(t *testing.T) { op := ops[0] results := map[string]int{} - var labels map[string]string + var attributes map[string]string mock1 := testutil.NewMockOperator("$.output1") mock1.On("Process", mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { results["output1"] = results["output1"] + 1 if entry, ok := args[1].(*entry.Entry); ok { - labels = entry.Labels + attributes = entry.Attributes } }) @@ -215,7 +215,7 @@ func TestRouterOperator(t *testing.T) { mock2.On("Process", mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { results["output2"] = results["output2"] + 1 if entry, ok := args[1].(*entry.Entry); ok { - labels = entry.Labels + attributes = entry.Attributes } }) @@ -227,7 +227,7 @@ func TestRouterOperator(t *testing.T) { require.NoError(t, err) require.Equal(t, tc.expectedCounts, results) - require.Equal(t, tc.expectedLabels, labels) + require.Equal(t, tc.expectedAttributes, attributes) }) } } diff --git a/operator/helper/attributer.go b/operator/helper/attributer.go new file mode 100644 index 00000000..342e4a10 --- /dev/null +++ b/operator/helper/attributer.go @@ -0,0 +1,74 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helper + +import ( + "github.com/open-telemetry/opentelemetry-log-collection/entry" +) + +// NewAttributerConfig creates a new attributer config with default values +func NewAttributerConfig() AttributerConfig { + return AttributerConfig{ + Attributes: make(map[string]ExprStringConfig), + } +} + +// AttributerConfig is the configuration of a attributer +type AttributerConfig struct { + Attributes map[string]ExprStringConfig `mapstructure:"attributes" json:"attributes" yaml:"attributes"` +} + +// Build will build a attributer from the supplied configuration +func (c AttributerConfig) Build() (Attributer, error) { + attributer := Attributer{ + attributes: make(map[string]*ExprString), + } + + for k, v := range c.Attributes { + exprString, err := v.Build() + if err != nil { + return attributer, err + } + + attributer.attributes[k] = exprString + } + + return attributer, nil +} + +// Attributer is a helper that adds attributes to an entry +type Attributer struct { + attributes map[string]*ExprString +} + +// Attribute will add attributes to an entry +func (l *Attributer) Attribute(e *entry.Entry) error { + if len(l.attributes) == 0 { + return nil + } + + env := GetExprEnv(e) + defer PutExprEnv(env) + + for k, v := range l.attributes { + rendered, err := v.Render(env) + if err != nil { + return err + } + e.AddAttribute(k, rendered) + } + + return nil +} diff --git a/operator/helper/labeler_test.go b/operator/helper/attributer_test.go similarity index 69% rename from operator/helper/labeler_test.go rename to operator/helper/attributer_test.go index 3053d05a..d6881a86 100644 --- a/operator/helper/labeler_test.go +++ b/operator/helper/attributer_test.go @@ -22,21 +22,21 @@ import ( "github.com/stretchr/testify/require" ) -func TestLabeler(t *testing.T) { +func TestAttributer(t *testing.T) { os.Setenv("TEST_METADATA_PLUGIN_ENV", "foo") defer os.Unsetenv("TEST_METADATA_PLUGIN_ENV") cases := []struct { name string - config LabelerConfig + config AttributerConfig input *entry.Entry expected *entry.Entry }{ { - "AddLabelLiteral", - func() LabelerConfig { - cfg := NewLabelerConfig() - cfg.Labels = map[string]ExprStringConfig{ + "AddAttributeLiteral", + func() AttributerConfig { + cfg := NewAttributerConfig() + cfg.Attributes = map[string]ExprStringConfig{ "label1": "value1", } return cfg @@ -44,17 +44,17 @@ func TestLabeler(t *testing.T) { entry.New(), func() *entry.Entry { e := entry.New() - e.Labels = map[string]string{ + e.Attributes = map[string]string{ "label1": "value1", } return e }(), }, { - "AddLabelExpr", - func() LabelerConfig { - cfg := NewLabelerConfig() - cfg.Labels = map[string]ExprStringConfig{ + "AddAttributeExpr", + func() AttributerConfig { + cfg := NewAttributerConfig() + cfg.Attributes = map[string]ExprStringConfig{ "label1": `EXPR("start" + "end")`, } return cfg @@ -62,17 +62,17 @@ func TestLabeler(t *testing.T) { entry.New(), func() *entry.Entry { e := entry.New() - e.Labels = map[string]string{ + e.Attributes = map[string]string{ "label1": "startend", } return e }(), }, { - "AddLabelEnv", - func() LabelerConfig { - cfg := NewLabelerConfig() - cfg.Labels = map[string]ExprStringConfig{ + "AddAttributeEnv", + func() AttributerConfig { + cfg := NewAttributerConfig() + cfg.Attributes = map[string]ExprStringConfig{ "label1": `EXPR(env("TEST_METADATA_PLUGIN_ENV"))`, } return cfg @@ -80,7 +80,7 @@ func TestLabeler(t *testing.T) { entry.New(), func() *entry.Entry { e := entry.New() - e.Labels = map[string]string{ + e.Attributes = map[string]string{ "label1": "foo", } return e @@ -90,12 +90,12 @@ func TestLabeler(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - labeler, err := tc.config.Build() + attributer, err := tc.config.Build() require.NoError(t, err) - err = labeler.Label(tc.input) + err = attributer.Attribute(tc.input) require.NoError(t, err) - require.Equal(t, tc.expected.Labels, tc.input.Labels) + require.Equal(t, tc.expected.Attributes, tc.input.Attributes) }) } } diff --git a/operator/helper/expr_string.go b/operator/helper/expr_string.go index 71a55dd2..543700f0 100644 --- a/operator/helper/expr_string.go +++ b/operator/helper/expr_string.go @@ -142,7 +142,7 @@ func GetExprEnv(e *entry.Entry) map[string]interface{} { env := envPool.Get().(map[string]interface{}) env["$"] = e.Record env["$record"] = e.Record - env["$labels"] = e.Labels + env["$attributes"] = e.Attributes env["$resource"] = e.Resource env["$timestamp"] = e.Timestamp diff --git a/operator/helper/host_identifier.go b/operator/helper/host_identifier.go index f8f474a1..c7363d78 100644 --- a/operator/helper/host_identifier.go +++ b/operator/helper/host_identifier.go @@ -42,7 +42,7 @@ type HostIdentifierConfig struct { getIP func() (string, error) } -// Build will build a host labeler from the supplied configuration +// Build will build a host attributer from the supplied configuration func (c HostIdentifierConfig) Build() (HostIdentifier, error) { identifier := HostIdentifier{ includeHostname: c.IncludeHostname, diff --git a/operator/helper/host_identifier_test.go b/operator/helper/host_identifier_test.go index 138459ae..c2db5c1b 100644 --- a/operator/helper/host_identifier_test.go +++ b/operator/helper/host_identifier_test.go @@ -30,7 +30,7 @@ func MockHostIdentifierConfig(includeIP, includeHostname bool, ip, hostname stri } } -func TestHostLabeler(t *testing.T) { +func TestHostAttributer(t *testing.T) { cases := []struct { name string config HostIdentifierConfig diff --git a/operator/helper/identifier_test.go b/operator/helper/identifier_test.go index 20e1cb0f..cb6923a8 100644 --- a/operator/helper/identifier_test.go +++ b/operator/helper/identifier_test.go @@ -33,7 +33,7 @@ func TestIdentifier(t *testing.T) { expected *entry.Entry }{ { - "AddLabelLiteral", + "AddAttributeLiteral", func() IdentifierConfig { cfg := NewIdentifierConfig() cfg.Resource = map[string]ExprStringConfig{ @@ -51,7 +51,7 @@ func TestIdentifier(t *testing.T) { }(), }, { - "AddLabelExpr", + "AddAttributeExpr", func() IdentifierConfig { cfg := NewIdentifierConfig() cfg.Resource = map[string]ExprStringConfig{ @@ -69,7 +69,7 @@ func TestIdentifier(t *testing.T) { }(), }, { - "AddLabelEnv", + "AddAttributeEnv", func() IdentifierConfig { cfg := NewIdentifierConfig() cfg.Resource = map[string]ExprStringConfig{ diff --git a/operator/helper/input.go b/operator/helper/input.go index d8b87084..4cba28f0 100644 --- a/operator/helper/input.go +++ b/operator/helper/input.go @@ -26,7 +26,7 @@ import ( // NewInputConfig creates a new input config with default values. func NewInputConfig(operatorID, operatorType string) InputConfig { return InputConfig{ - LabelerConfig: NewLabelerConfig(), + AttributerConfig: NewAttributerConfig(), IdentifierConfig: NewIdentifierConfig(), WriterConfig: NewWriterConfig(operatorID, operatorType), WriteTo: entry.NewRecordField(), @@ -35,7 +35,7 @@ func NewInputConfig(operatorID, operatorType string) InputConfig { // InputConfig provides a basic implementation of an input operator config. type InputConfig struct { - LabelerConfig `mapstructure:",squash" yaml:",inline"` + AttributerConfig `mapstructure:",squash" yaml:",inline"` IdentifierConfig `mapstructure:",squash" yaml:",inline"` WriterConfig `mapstructure:",squash" yaml:",inline"` WriteTo entry.Field `mapstructure:"write_to" json:"write_to" yaml:"write_to"` @@ -48,7 +48,7 @@ func (c InputConfig) Build(context operator.BuildContext) (InputOperator, error) return InputOperator{}, errors.WithDetails(err, "operator_id", c.ID()) } - labeler, err := c.LabelerConfig.Build() + attributer, err := c.AttributerConfig.Build() if err != nil { return InputOperator{}, errors.WithDetails(err, "operator_id", c.ID()) } @@ -59,7 +59,7 @@ func (c InputConfig) Build(context operator.BuildContext) (InputOperator, error) } inputOperator := InputOperator{ - Labeler: labeler, + Attributer: attributer, Identifier: identifier, WriterOperator: writerOperator, WriteTo: c.WriteTo, @@ -70,21 +70,21 @@ func (c InputConfig) Build(context operator.BuildContext) (InputOperator, error) // InputOperator provides a basic implementation of an input operator. type InputOperator struct { - Labeler + Attributer Identifier WriterOperator WriteTo entry.Field } -// NewEntry will create a new entry using the `write_to`, `labels`, and `resource` configuration. +// NewEntry will create a new entry using the `write_to`, `attributes`, and `resource` configuration. func (i *InputOperator) NewEntry(value interface{}) (*entry.Entry, error) { entry := entry.New() if err := entry.Set(i.WriteTo, value); err != nil { return nil, errors.Wrap(err, "add record to entry") } - if err := i.Label(entry); err != nil { - return nil, errors.Wrap(err, "add labels to entry") + if err := i.Attribute(entry); err != nil { + return nil, errors.Wrap(err, "add attributes to entry") } if err := i.Identify(entry); err != nil { diff --git a/operator/helper/input_test.go b/operator/helper/input_test.go index b8eb601e..64e86bec 100644 --- a/operator/helper/input_test.go +++ b/operator/helper/input_test.go @@ -110,8 +110,8 @@ func TestInputOperatorNewEntry(t *testing.T) { require.NoError(t, err) input := InputOperator{ - Labeler: Labeler{ - labels: map[string]*ExprString{ + Attributer: Attributer{ + attributes: map[string]*ExprString{ "test-label": labelExpr, }, }, @@ -137,7 +137,7 @@ func TestInputOperatorNewEntry(t *testing.T) { require.True(t, exists) require.Equal(t, "test", value) - labelValue, exists := entry.Labels["test-label"] + labelValue, exists := entry.Attributes["test-label"] require.True(t, exists) require.Equal(t, "test", labelValue) diff --git a/operator/helper/labeler.go b/operator/helper/labeler.go deleted file mode 100644 index 0920bcce..00000000 --- a/operator/helper/labeler.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package helper - -import ( - "github.com/open-telemetry/opentelemetry-log-collection/entry" -) - -// NewLabelerConfig creates a new labeler config with default values -func NewLabelerConfig() LabelerConfig { - return LabelerConfig{ - Labels: make(map[string]ExprStringConfig), - } -} - -// LabelerConfig is the configuration of a labeler -type LabelerConfig struct { - Labels map[string]ExprStringConfig `mapstructure:"labels" json:"labels" yaml:"labels"` -} - -// Build will build a labeler from the supplied configuration -func (c LabelerConfig) Build() (Labeler, error) { - labeler := Labeler{ - labels: make(map[string]*ExprString), - } - - for k, v := range c.Labels { - exprString, err := v.Build() - if err != nil { - return labeler, err - } - - labeler.labels[k] = exprString - } - - return labeler, nil -} - -// Labeler is a helper that adds labels to an entry -type Labeler struct { - labels map[string]*ExprString -} - -// Label will add labels to an entry -func (l *Labeler) Label(e *entry.Entry) error { - if len(l.labels) == 0 { - return nil - } - - env := GetExprEnv(e) - defer PutExprEnv(env) - - for k, v := range l.labels { - rendered, err := v.Render(env) - if err != nil { - return err - } - e.AddLabel(k, rendered) - } - - return nil -} diff --git a/plugin/parameter.go b/plugin/parameter.go index 8ecce11e..ebaf7bc1 100644 --- a/plugin/parameter.go +++ b/plugin/parameter.go @@ -31,7 +31,7 @@ const ( // Parameter is a basic description of a plugin's parameter. type Parameter struct { Name string `json:"name" yaml:"name"` - Label string `json:"label" yaml:"label"` + Attribute string `json:"label" yaml:"label"` Description string `json:"description" yaml:"description"` Required bool `json:"required" yaml:"required"` From 91101bafcec4d92f2b43737a2fbb8c64d2f6d825 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Fri, 5 Mar 2021 16:29:27 -0500 Subject: [PATCH 2/2] Roll back a few mistaken renamed fields --- CHANGELOG.md | 9 +++++++-- plugin/parameter.go | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e73ba960..2ab40b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed +- Rename `entry.Label` to `entry.Attribute` + ## [0.15.1] - 2020-03-01 ### Added @@ -182,8 +187,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `Tags` field was removed from Entry ([PR95](https://github.com/observIQ/stanza/pull/95)) ### Changed -- The `host_metadata` operator now writes to an entry's `Resource` field, instead of Attributes -- The `host_attributer` helper has been renamed `host_identifier` +- The `host_metadata` operator now writes to an entry's `Resource` field, instead of Labels +- The `host_labeler` helper has been renamed `host_identifier` - The `metadata` operator embeds the `Identifier` helper and supports writing to `Resource` - Input operators embed the `Identifier` helper and support writing to `Resource` - The `k8s_event` operator now supports the `write_to`, `labels`, and `resource` configuration options diff --git a/plugin/parameter.go b/plugin/parameter.go index ebaf7bc1..8ecce11e 100644 --- a/plugin/parameter.go +++ b/plugin/parameter.go @@ -31,7 +31,7 @@ const ( // Parameter is a basic description of a plugin's parameter. type Parameter struct { Name string `json:"name" yaml:"name"` - Attribute string `json:"label" yaml:"label"` + Label string `json:"label" yaml:"label"` Description string `json:"description" yaml:"description"` Required bool `json:"required" yaml:"required"`