Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
loki/clients/pkg/promtail/targets/gcplog/formatter.go

131 lines
3.7 KiB

5 years ago
package gcplog
import (
"fmt"
"strings"
"time"
json "github.com/json-iterator/go"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/model/relabel"
5 years ago
"github.com/grafana/loki/v3/clients/pkg/promtail/api"
"github.com/grafana/loki/v3/pkg/logproto"
5 years ago
)
// GCPLogEntry that will be written to the pubsub topic.
5 years ago
// According to the following spec.
// https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
// nolint:revive
5 years ago
type GCPLogEntry struct {
LogName string `json:"logName"`
Resource struct {
Type string `json:"type"`
Labels map[string]string `json:"labels"`
} `json:"resource"`
Timestamp string `json:"timestamp"`
// The time the log entry was received by Logging.
// Its important that `Timestamp` is optional in GCE log entry.
ReceiveTimestamp string `json:"receiveTimestamp"`
// Optional. The severity of the log entry. The default value is DEFAULT.
// DEFAULT, DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
// https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
Severity string `json:"severity"`
// Optional. A map of key, value pairs that provides additional information about the log entry.
// The labels can be user-defined or system-defined.
Labels map[string]string `json:"labels"`
5 years ago
TextPayload string `json:"textPayload"`
// NOTE(kavi): There are other fields on GCPLogEntry. but we need only need above fields for now
// anyway we will be sending the entire entry to Loki.
}
func parseGCPLogsEntry(data []byte, other model.LabelSet, otherInternal labels.Labels, useIncomingTimestamp, useFullLine bool, relabelConfig []*relabel.Config) (api.Entry, error) {
5 years ago
var ge GCPLogEntry
Improvements to Promtail GCP push target (#7057) <!-- Thanks for sending a pull request! Before submitting: 1. Read our CONTRIBUTING.md guide 2. Name your PR as `<Feature Area>: Describe your change`. a. Do not end the title with punctuation. It will be added in the changelog. b. Start with an imperative verb. Example: Fix the latency between System A and System B. c. Use sentence case, not title case. d. Use a complete phrase or sentence. The PR title will appear in a changelog, so help other people understand what your change will be. 3. Rebase your PR if it gets out of sync with main --> **What this PR does / why we need it**: This PR includes some pending improvements to newish promtail GCP push target: - Pending low hanging optimization for replacing a regex that gets evaluated on every incoming request from GCP, for a simpler solution. [Related comments](https://github.com/grafana/loki/pull/6777#discussion_r935804383) - Some small refactors. See: [this](https://github.com/grafana/loki/pull/6777#pullrequestreview-1059064564) - Add some validations over the payload the target receives. Payload details are [here](https://cloud.google.com/pubsub/docs/push). This PR adds just validation over the log line, the incoming GCP message ID to add some traceability if needed, and the subscription name because it can be used as label. - Add `subscription` GCP payload field as label, which includes the PubSub subscription identifier. - Add `cause` label to error metrics. Since there's multiple failure point this might help debugging / notice strange behaviours. Also, by running the push target in some dev workloads, we noticed it has some labels different to the ones added in the pull target. This PR also refactors the logic to re-use the same GCP log entry parsing logic in both targets. That way the labels exposed to the user in the push target are $Labels_{pull} \cup Labels_{push}$. **Which issue(s) this PR fixes**: Related to: https://github.com/grafana/cloud-onboarding/issues/2067 **Special notes for your reviewer**: This PR is a follow up [this other one](https://github.com/grafana/loki/pull/6777). It works on some comments made after merge, and adds some changes we saw necessary upon running this target in real environments. <!-- Note about CHANGELOG entries, if a change adds: * an important feature * fixes an issue present in a previous release, * causes a change in operation that would be useful for an operator of Loki to know then please add a CHANGELOG entry. For documentation changes, build changes, simple fixes etc please skip this step. We are attempting to curate a changelog of the most relevant and important changes to be easier to ingest by end users of Loki. Note about the upgrade guide, if this changes: * default configuration values * metric names or label names * changes existing log lines such as the metrics.go query output line * configuration parameters * anything to do with any API * any other change that would require special attention or extra steps to upgrade Please document clearly what changed AND what needs to be done in the upgrade guide. --> **Checklist** - [x] Documentation added - [x] Tests updated - [ ] Is this an important fix or new feature? Add an entry in the `CHANGELOG.md`. - [ ] Changes that require user attention or interaction to upgrade are documented in `docs/sources/upgrading/_index.md` Co-authored-by: Kaviraj Kanagaraj <kavirajkanagaraj@gmail.com>
3 years ago
if err := json.Unmarshal(data, &ge); err != nil {
5 years ago
return api.Entry{}, err
}
Improvements to Promtail GCP push target (#7057) <!-- Thanks for sending a pull request! Before submitting: 1. Read our CONTRIBUTING.md guide 2. Name your PR as `<Feature Area>: Describe your change`. a. Do not end the title with punctuation. It will be added in the changelog. b. Start with an imperative verb. Example: Fix the latency between System A and System B. c. Use sentence case, not title case. d. Use a complete phrase or sentence. The PR title will appear in a changelog, so help other people understand what your change will be. 3. Rebase your PR if it gets out of sync with main --> **What this PR does / why we need it**: This PR includes some pending improvements to newish promtail GCP push target: - Pending low hanging optimization for replacing a regex that gets evaluated on every incoming request from GCP, for a simpler solution. [Related comments](https://github.com/grafana/loki/pull/6777#discussion_r935804383) - Some small refactors. See: [this](https://github.com/grafana/loki/pull/6777#pullrequestreview-1059064564) - Add some validations over the payload the target receives. Payload details are [here](https://cloud.google.com/pubsub/docs/push). This PR adds just validation over the log line, the incoming GCP message ID to add some traceability if needed, and the subscription name because it can be used as label. - Add `subscription` GCP payload field as label, which includes the PubSub subscription identifier. - Add `cause` label to error metrics. Since there's multiple failure point this might help debugging / notice strange behaviours. Also, by running the push target in some dev workloads, we noticed it has some labels different to the ones added in the pull target. This PR also refactors the logic to re-use the same GCP log entry parsing logic in both targets. That way the labels exposed to the user in the push target are $Labels_{pull} \cup Labels_{push}$. **Which issue(s) this PR fixes**: Related to: https://github.com/grafana/cloud-onboarding/issues/2067 **Special notes for your reviewer**: This PR is a follow up [this other one](https://github.com/grafana/loki/pull/6777). It works on some comments made after merge, and adds some changes we saw necessary upon running this target in real environments. <!-- Note about CHANGELOG entries, if a change adds: * an important feature * fixes an issue present in a previous release, * causes a change in operation that would be useful for an operator of Loki to know then please add a CHANGELOG entry. For documentation changes, build changes, simple fixes etc please skip this step. We are attempting to curate a changelog of the most relevant and important changes to be easier to ingest by end users of Loki. Note about the upgrade guide, if this changes: * default configuration values * metric names or label names * changes existing log lines such as the metrics.go query output line * configuration parameters * anything to do with any API * any other change that would require special attention or extra steps to upgrade Please document clearly what changed AND what needs to be done in the upgrade guide. --> **Checklist** - [x] Documentation added - [x] Tests updated - [ ] Is this an important fix or new feature? Add an entry in the `CHANGELOG.md`. - [ ] Changes that require user attention or interaction to upgrade are documented in `docs/sources/upgrading/_index.md` Co-authored-by: Kaviraj Kanagaraj <kavirajkanagaraj@gmail.com>
3 years ago
// Mixin with otherInternal labels coming from upstream that need processing
// Adding mandatory labels for gcplog
lbs := labels.NewBuilder(otherInternal)
lbs.Set("__gcp_logname", ge.LogName)
lbs.Set("__gcp_resource_type", ge.Resource.Type)
lbs.Set("__gcp_severity", ge.Severity)
// resource labels from gcp log entry. Add it as internal labels
for k, v := range ge.Resource.Labels {
lbs.Set("__gcp_resource_labels_"+convertToLokiCompatibleLabel(k), v)
}
// labels from gcp log entry. Add it as internal labels
for k, v := range ge.Labels {
lbs.Set("__gcp_labels_"+convertToLokiCompatibleLabel(k), v)
}
var processed labels.Labels
// apply relabeling
if len(relabelConfig) > 0 {
processed, _ = relabel.Process(lbs.Labels(), relabelConfig...)
} else {
processed = lbs.Labels()
}
// final labelset that will be sent to loki
labels := make(model.LabelSet)
for _, lbl := range processed {
// ignore internal labels
if strings.HasPrefix(lbl.Name, "__") {
continue
}
// ignore invalid labels
if !model.LabelName(lbl.Name).IsValid() || !model.LabelValue(lbl.Value).IsValid() {
continue
}
labels[model.LabelName(lbl.Name)] = model.LabelValue(lbl.Value)
5 years ago
}
// add labels coming from scrapeconfig
5 years ago
labels = labels.Merge(other)
ts := time.Now()
Improvements to Promtail GCP push target (#7057) <!-- Thanks for sending a pull request! Before submitting: 1. Read our CONTRIBUTING.md guide 2. Name your PR as `<Feature Area>: Describe your change`. a. Do not end the title with punctuation. It will be added in the changelog. b. Start with an imperative verb. Example: Fix the latency between System A and System B. c. Use sentence case, not title case. d. Use a complete phrase or sentence. The PR title will appear in a changelog, so help other people understand what your change will be. 3. Rebase your PR if it gets out of sync with main --> **What this PR does / why we need it**: This PR includes some pending improvements to newish promtail GCP push target: - Pending low hanging optimization for replacing a regex that gets evaluated on every incoming request from GCP, for a simpler solution. [Related comments](https://github.com/grafana/loki/pull/6777#discussion_r935804383) - Some small refactors. See: [this](https://github.com/grafana/loki/pull/6777#pullrequestreview-1059064564) - Add some validations over the payload the target receives. Payload details are [here](https://cloud.google.com/pubsub/docs/push). This PR adds just validation over the log line, the incoming GCP message ID to add some traceability if needed, and the subscription name because it can be used as label. - Add `subscription` GCP payload field as label, which includes the PubSub subscription identifier. - Add `cause` label to error metrics. Since there's multiple failure point this might help debugging / notice strange behaviours. Also, by running the push target in some dev workloads, we noticed it has some labels different to the ones added in the pull target. This PR also refactors the logic to re-use the same GCP log entry parsing logic in both targets. That way the labels exposed to the user in the push target are $Labels_{pull} \cup Labels_{push}$. **Which issue(s) this PR fixes**: Related to: https://github.com/grafana/cloud-onboarding/issues/2067 **Special notes for your reviewer**: This PR is a follow up [this other one](https://github.com/grafana/loki/pull/6777). It works on some comments made after merge, and adds some changes we saw necessary upon running this target in real environments. <!-- Note about CHANGELOG entries, if a change adds: * an important feature * fixes an issue present in a previous release, * causes a change in operation that would be useful for an operator of Loki to know then please add a CHANGELOG entry. For documentation changes, build changes, simple fixes etc please skip this step. We are attempting to curate a changelog of the most relevant and important changes to be easier to ingest by end users of Loki. Note about the upgrade guide, if this changes: * default configuration values * metric names or label names * changes existing log lines such as the metrics.go query output line * configuration parameters * anything to do with any API * any other change that would require special attention or extra steps to upgrade Please document clearly what changed AND what needs to be done in the upgrade guide. --> **Checklist** - [x] Documentation added - [x] Tests updated - [ ] Is this an important fix or new feature? Add an entry in the `CHANGELOG.md`. - [ ] Changes that require user attention or interaction to upgrade are documented in `docs/sources/upgrading/_index.md` Co-authored-by: Kaviraj Kanagaraj <kavirajkanagaraj@gmail.com>
3 years ago
line := string(data)
5 years ago
if useIncomingTimestamp {
tt := ge.Timestamp
if tt == "" {
tt = ge.ReceiveTimestamp
}
var err error
ts, err = time.Parse(time.RFC3339, tt)
if err != nil {
return api.Entry{}, fmt.Errorf("invalid timestamp format: %w", err)
}
if ts.IsZero() {
return api.Entry{}, fmt.Errorf("no timestamp found in the log entry")
}
}
// Send only `ge.textPayload` as log line if its present and user don't explicitly ask for the whole log.
if !useFullLine && strings.TrimSpace(ge.TextPayload) != "" {
5 years ago
line = ge.TextPayload
}
return api.Entry{
Labels: labels,
Entry: logproto.Entry{
Timestamp: ts,
Line: line,
},
}, nil
}