diff --git a/internal/collector/nginxossreceiver/internal/record/recorder.go b/internal/collector/nginxossreceiver/internal/record/recorder.go deleted file mode 100644 index ee8bee3103..0000000000 --- a/internal/collector/nginxossreceiver/internal/record/recorder.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) F5, Inc. -// -// This source code is licensed under the Apache License, Version 2.0 license found in the -// LICENSE file in the root directory of this source tree. - -package record - -import ( - "fmt" - "strconv" - "time" - - "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/metadata" - "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/model" - "go.opentelemetry.io/collector/pdata/pcommon" -) - -const ( - // Needed for "magic number" linter. - status100 = 100 - status200 = 200 - status300 = 300 - status400 = 400 - status500 = 500 - - percent = 100 -) - -// Item extracts data from NGINX Access Items and records them using the given MetricsBuilder. -func Item(ai *model.NginxAccessItem, mb *metadata.MetricsBuilder) error { - now := pcommon.NewTimestampFromTime(time.Now()) - - if ai.Status != "" { - codeRange, err := mapCodeRange(ai.Status) - if err != nil { - return fmt.Errorf("parse status range: %w", err) - } - - mb.RecordNginxHTTPResponseStatusDataPoint(now, 1, codeRange) - } - - return nil -} - -func mapCodeRange(statusCode string) (metadata.AttributeNginxStatusRange, error) { - number, err := strconv.Atoi(statusCode) - if err != nil { - return 0, fmt.Errorf("cast status code to int: %w", err) - } - - // We want to "floor" the response code, so we can map it to the correct range (i.e. to 1xx, 2xx, 4xx or 5xx). - codeRange := (number / percent) * percent - - switch codeRange { - case status100: - return metadata.AttributeNginxStatusRange1xx, nil - case status200: - return metadata.AttributeNginxStatusRange2xx, nil - case status300: - return metadata.AttributeNginxStatusRange3xx, nil - case status400: - return metadata.AttributeNginxStatusRange4xx, nil - case status500: - return metadata.AttributeNginxStatusRange5xx, nil - default: - return 0, fmt.Errorf("unknown code range: %d", codeRange) - } -} diff --git a/internal/collector/nginxossreceiver/internal/record/recorder_test.go b/internal/collector/nginxossreceiver/internal/record/recorder_test.go deleted file mode 100644 index a99c7a725a..0000000000 --- a/internal/collector/nginxossreceiver/internal/record/recorder_test.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) F5, Inc. -// -// This source code is licensed under the Apache License, Version 2.0 license found in the -// LICENSE file in the root directory of this source tree. - -package record - -import ( - "errors" - "path/filepath" - "testing" - - "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/metadata" - "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/model" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/receiver/receivertest" -) - -const testDataDir = "testdata" - -func TestRecordAccessItem(t *testing.T) { - tests := []struct { - name string - expectedPath string - expErrMsg string - input []*model.NginxAccessItem - shouldErr bool - }{ - { - name: "Test 1: basic nginx.http.response.status case", - input: []*model.NginxAccessItem{ - { - BodyBytesSent: "615", - Status: "200", - RemoteAddress: "127.0.0.1", - HTTPUserAgent: "PostmanRuntime/7.36.1", - Request: "GET / HTTP/1.1", - BytesSent: "853", - RequestLength: "226", - RequestTime: "0.000", - GzipRatio: "-", - ServerProtocol: "HTTP/1.1", - UpstreamConnectTime: "-", - UpstreamHeaderTime: "-", - UpstreamResponseTime: "-", - UpstreamResponseLength: "-", - UpstreamStatus: "", - UpstreamCacheStatus: "", - }, - { - BodyBytesSent: "28", - Status: "200", - RemoteAddress: "127.0.0.1", - HTTPUserAgent: "PostmanRuntime/7.36.1", - Request: "GET /frontend1 HTTP/1.1", - BytesSent: "190", - RequestLength: "235", - RequestTime: "0.004", - GzipRatio: "-", - ServerProtocol: "HTTP/1.1", - UpstreamConnectTime: "0.003", - UpstreamHeaderTime: "0.003", - UpstreamResponseTime: "0.003", - UpstreamResponseLength: "28", - UpstreamStatus: "", - UpstreamCacheStatus: "", - }, - }, - expectedPath: "basic-nginx.http.response.status.yaml", - }, - { - name: "Test 2: all nginx.http.response.status status codes", - input: []*model.NginxAccessItem{ - { // The recorder only parses the status code for this metric, omitting other fields for brevity. - Status: "100", - }, - { - Status: "103", - }, - { - Status: "200", - }, - { - Status: "202", - }, - { - Status: "300", - }, - { - Status: "302", - }, - { - Status: "400", - }, - { - Status: "404", - }, - { - Status: "500", - }, - { - Status: "502", - }, - }, - expectedPath: "multicode-nginx.http.response.status.yaml", - }, - { - name: "Test 3: random string in status code", - input: []*model.NginxAccessItem{ - { - Status: "not-a-status-code", - }, - }, - shouldErr: true, - expErrMsg: "cast status code to int", - }, - { - name: "Test 4: non-existent status code range", - input: []*model.NginxAccessItem{ - { - Status: "700", - }, - }, - shouldErr: true, - expErrMsg: "unknown code range: 700", - }, - } - - mb := metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopSettings()) - - for _, test := range tests { - t.Run(test.name, func(tt *testing.T) { - var err error - for _, item := range test.input { - recordErr := Item(item, mb) - err = errors.Join(err, recordErr) - } - - if test.shouldErr { - require.Error(tt, err) - assert.Contains(tt, err.Error(), test.expErrMsg) - } else { - require.NoError(tt, err) - expectedFile := filepath.Join(testDataDir, test.expectedPath) - expected, readErr := golden.ReadMetrics(expectedFile) - require.NoError(t, readErr) - - actual := mb.Emit() - require.NoError(tt, pmetrictest.CompareMetrics(expected, actual, - pmetrictest.IgnoreStartTimestamp(), - pmetrictest.IgnoreMetricDataPointsOrder(), - pmetrictest.IgnoreTimestamp(), - pmetrictest.IgnoreMetricsOrder())) - } - }) - } -} diff --git a/internal/collector/nginxossreceiver/internal/record/testdata/basic-nginx.http.response.status.yaml b/internal/collector/nginxossreceiver/internal/record/testdata/basic-nginx.http.response.status.yaml deleted file mode 100644 index 994992e871..0000000000 --- a/internal/collector/nginxossreceiver/internal/record/testdata/basic-nginx.http.response.status.yaml +++ /dev/null @@ -1,26 +0,0 @@ -resourceMetrics: - - resource: {} - scopeMetrics: - - metrics: - - description: The number of responses, grouped by status code range. - name: nginx.http.response.status - sum: - aggregationTemporality: 2 # Cumulative - isMonotonic: true - dataPoints: - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "2xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "2xx" - timeUnixNano: "1000000" - unit: responses - scope: - name: otelcol/nginxreceiver - version: latest diff --git a/internal/collector/nginxossreceiver/internal/record/testdata/multicode-nginx.http.response.status.yaml b/internal/collector/nginxossreceiver/internal/record/testdata/multicode-nginx.http.response.status.yaml deleted file mode 100644 index 38ee8518dc..0000000000 --- a/internal/collector/nginxossreceiver/internal/record/testdata/multicode-nginx.http.response.status.yaml +++ /dev/null @@ -1,73 +0,0 @@ -resourceMetrics: - - resource: {} - scopeMetrics: - - metrics: - - description: The number of responses, grouped by status code range. - name: nginx.http.response.status - sum: - aggregationTemporality: 2 # Cumulative - isMonotonic: true - dataPoints: - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "1xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "1xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "2xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "2xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "3xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "3xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "4xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "4xx" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "5xx" - timeUnixNano: "1000000" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "5xx" - timeUnixNano: "1000000" - unit: responses - scope: - name: otelcol/nginxreceiver - version: latest diff --git a/internal/collector/nginxossreceiver/internal/scraper/accesslog/nginx_log_scraper.go b/internal/collector/nginxossreceiver/internal/scraper/accesslog/nginx_log_scraper.go index 93391655d9..1868fa0e68 100644 --- a/internal/collector/nginxossreceiver/internal/scraper/accesslog/nginx_log_scraper.go +++ b/internal/collector/nginxossreceiver/internal/scraper/accesslog/nginx_log_scraper.go @@ -8,7 +8,11 @@ package accesslog import ( "context" "fmt" + "strconv" "sync" + "time" + + "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" @@ -27,10 +31,11 @@ import ( "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/config" "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/metadata" "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/model" - "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/record" "github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/scraper/accesslog/operator/input/file" ) +const Percentage = 100 + type ( NginxLogScraper struct { outChan <-chan []*entry.Entry @@ -43,6 +48,18 @@ type ( entries []*entry.Entry mut sync.Mutex } + + NginxMetrics struct { + responseStatuses ResponseStatuses + } + + ResponseStatuses struct { + oneHundredStatusRange int64 + twoHundredStatusRange int64 + threeHundredStatusRange int64 + fourHundredStatusRange int64 + fiveHundredStatusRange int64 + } ) var _ scraperhelper.Scraper = (*NginxLogScraper)(nil) @@ -55,7 +72,7 @@ func NewScraper( logger.Info("Creating NGINX access log scraper") mb := metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings) - operators := []operator.Config{} + operators := make([]operator.Config, 0) for _, accessLog := range cfg.AccessLogs { logger.Info("Adding access log file operator", zap.String("file_path", accessLog.FilePath)) @@ -106,21 +123,66 @@ func (nls *NginxLogScraper) Start(parentCtx context.Context, _ component.Host) e func (nls *NginxLogScraper) Scrape(_ context.Context) (pmetric.Metrics, error) { nls.mut.Lock() defer nls.mut.Unlock() + + nginxMetrics := NginxMetrics{} + for _, ent := range nls.entries { - nls.logger.Info("Scraping NGINX access log", zap.Any("entity", ent)) + nls.logger.Debug("Scraping NGINX access log", zap.Any("entity", ent)) item, ok := ent.Body.(*model.NginxAccessItem) if !ok { - nls.logger.Info("Failed to cast log entry to *model.NginxAccessItem", zap.Any("entry", ent.Body)) + nls.logger.Warn("Failed to cast log entry to *model.NginxAccessItem", zap.Any("entry", ent.Body)) continue } - err := record.Item(item, nls.mb) - if err != nil { - nls.logger.Info("Recording metric failed", zap.Any("item", item), zap.Error(err)) - continue + if v, err := strconv.Atoi(item.Status); err == nil { + codeRange := fmt.Sprintf("%dxx", v/Percentage) + + switch codeRange { + case "1xx": + nginxMetrics.responseStatuses.oneHundredStatusRange++ + case "2xx": + nginxMetrics.responseStatuses.twoHundredStatusRange++ + case "3xx": + nginxMetrics.responseStatuses.threeHundredStatusRange++ + case "4xx": + nginxMetrics.responseStatuses.fourHundredStatusRange++ + case "5xx": + nginxMetrics.responseStatuses.fiveHundredStatusRange++ + default: + nls.logger.Error("Unknown status range", zap.String("codeRange", codeRange)) + continue + } } } + nls.entries = make([]*entry.Entry, 0) + timeNow := pcommon.NewTimestampFromTime(time.Now()) + + nls.mb.RecordNginxHTTPResponseStatusDataPoint( + timeNow, + nginxMetrics.responseStatuses.oneHundredStatusRange, + metadata.AttributeNginxStatusRange1xx, + ) + nls.mb.RecordNginxHTTPResponseStatusDataPoint( + timeNow, + nginxMetrics.responseStatuses.twoHundredStatusRange, + metadata.AttributeNginxStatusRange2xx, + ) + nls.mb.RecordNginxHTTPResponseStatusDataPoint( + timeNow, + nginxMetrics.responseStatuses.threeHundredStatusRange, + metadata.AttributeNginxStatusRange3xx, + ) + nls.mb.RecordNginxHTTPResponseStatusDataPoint( + timeNow, + nginxMetrics.responseStatuses.fourHundredStatusRange, + metadata.AttributeNginxStatusRange4xx, + ) + nls.mb.RecordNginxHTTPResponseStatusDataPoint( + timeNow, + nginxMetrics.responseStatuses.fiveHundredStatusRange, + metadata.AttributeNginxStatusRange5xx, + ) return nls.mb.Emit(), nil } diff --git a/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/expected.yaml b/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/expected.yaml index 94a4d72368..edc97f287a 100644 --- a/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/expected.yaml +++ b/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/expected.yaml @@ -8,48 +8,27 @@ resourceMetrics: aggregationTemporality: 2 # Cumulative isMonotonic: true dataPoints: - - asInt: 1 + - asInt: 0 attributes: - key: nginx.status_range value: - stringValue: 2xx - timeUnixNano: "1000000" - - asInt: 1 + stringValue: "1xx" + - asInt: 4 attributes: - key: nginx.status_range value: stringValue: "2xx" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "3xx" - - asInt: 1 + - asInt: 2 attributes: - key: nginx.status_range value: stringValue: "3xx" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "4xx" - - asInt: 1 + - asInt: 6 attributes: - key: nginx.status_range value: stringValue: "4xx" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "5xx" - - asInt: 1 - attributes: - - key: nginx.status_range - value: - stringValue: "5xx" - - asInt: 1 + - asInt: 3 attributes: - key: nginx.status_range value: diff --git a/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/test-access.log b/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/test-access.log index a9d8ed8349..9ebbe29294 100644 --- a/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/test-access.log +++ b/internal/collector/nginxossreceiver/internal/scraper/accesslog/testdata/test-access.log @@ -1,8 +1,14 @@ 127.0.0.1 - - [16/Apr/2024:09:00:45 +0100] "GET /example HTTP/1.0" 200 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" +127.0.0.1 - - [16/Apr/2024:09:00:45 +0100] "GET /example HTTP/1.0" 200 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" +127.0.0.1 - - [16/Apr/2024:09:00:45 +0100] "GET /example HTTP/1.0" 200 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" 127.0.0.1 - - [16/Apr/2024:09:00:45 +0100] "GET /example HTTP/1.1" 203 28 "-" "PostmanRuntime/7.36.1" "-" "190" "235" "0.004" "-" "HTTP/1.1" "0.003""0.003" "28" "0.003" 127.0.0.1 - - [16/Apr/2024:09:03:02 +0100] "GET /example HTTP/1.0" 300 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" 127.0.0.1 - - [16/Apr/2024:09:03:02 +0100] "GET /example HTTP/1.1" 303 28 "-" "PostmanRuntime/7.36.1" "-" "190" "235" "0.002" "-" "HTTP/1.1" "0.000""0.003" "28" "0.003" 127.0.0.1 - - [16/Apr/2024:10:57:45 +0100] "GET /example HTTP/1.0" 400 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" +127.0.0.1 - - [16/Apr/2024:10:57:45 +0100] "GET /example HTTP/1.0" 400 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" +127.0.0.1 - - [16/Apr/2024:10:57:45 +0100] "GET /example HTTP/1.0" 400 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" +127.0.0.1 - - [16/Apr/2024:10:57:45 +0100] "GET /example HTTP/1.0" 400 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" +127.0.0.1 - - [16/Apr/2024:10:57:45 +0100] "GET /example HTTP/1.0" 400 28 "-" "PostmanRuntime/7.36.1" "-" "185" "222" "0.000" "-" "HTTP/1.0" "-""-" "-" "-" 127.0.0.1 - - [16/Apr/2024:10:57:45 +0100] "GET /example HTTP/1.1" 401 28 "-" "PostmanRuntime/7.36.1" "-" "190" "235" "0.406" "-" "HTTP/1.1" "0.297""0.407" "28" "0.407" 127.0.0.1 - - [16/Apr/2024:10:57:55 +0100] "GET / HTTP/1.1" 500 615 "-" "PostmanRuntime/7.36.1" "-" "853" "226" "0.000" "-" "HTTP/1.1" "-""-" "-" "-" 127.0.0.1 - - [16/Apr/2024:10:58:25 +0100] "GET / HTTP/1.1" 502 615 "-" "PostmanRuntime/7.36.1" "-" "853" "226" "0.000" "-" "HTTP/1.1" "-""-" "-" "-" diff --git a/internal/config/defaults.go b/internal/config/defaults.go index cede509067..57d7903eb5 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -14,15 +14,14 @@ const ( DefNginxReloadMonitoringPeriod = 10 * time.Second DefTreatErrorsAsWarnings = true - DefCollectorConfigPath = "/var/run/nginx-agent/opentelemetry-collector-agent.yaml" - DefCollectorTLSGenSelfSignedCert = false - DefCollectorLogLevel = "INFO" - DefCollectorLogPath = "/var/log/nginx-agent/opentelemetry-collector-agent.log" - DefConfigDirectories = "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules" - DefCollectorTLSCertPath = "/var/lib/nginx-agent/cert.pem" - DefCollectorTLSKeyPath = "/var/lib/nginx-agent/key.pem" - DefCollectorTLSCAPath = "/var/lib/nginx-agent/ca.pem" - DefCollectorTLSSANNames = "127.0.0.1,::1,localhost" + DefCollectorConfigPath = "/etc/nginx-agent/opentelemetry-collector-agent.yaml" + DefCollectorLogLevel = "INFO" + DefCollectorLogPath = "/var/log/nginx-agent/opentelemetry-collector-agent.log" + DefConfigDirectories = "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules" + DefCollectorTLSCertPath = "/var/lib/nginx-agent/cert.pem" + DefCollectorTLSKeyPath = "/var/lib/nginx-agent/key.pem" + DefCollectorTLSCAPath = "/var/lib/nginx-agent/ca.pem" + DefCollectorTLSSANNames = "127.0.0.1,::1,localhost" DefCommandServerHostKey = "" DefCommandServerPortKey = 0 diff --git a/scripts/testing/load/Dockerfile b/scripts/testing/load/Dockerfile index c4fd26a277..af065a08fe 100644 --- a/scripts/testing/load/Dockerfile +++ b/scripts/testing/load/Dockerfile @@ -80,7 +80,7 @@ ENV PATH="/usr/local/go/bin:${PATH}" ENV PATH=$PATH:/usr/local/go/bin RUN mv /agent/test/config/agent/nginx-agent-otel-load.conf /agent/test/load/nginx-agent.conf -RUN mkdir /var/run/nginx-agent/ /var/log/nginx-agent/ +RUN mkdir /var/run/nginx-agent/ /var/log/nginx-agent/ /etc/nginx-agent/ WORKDIR /agent/ CMD make install-tools diff --git a/test/mock/collector/grafana/provisioning/dashboards/host-metrics.json b/test/mock/collector/grafana/provisioning/dashboards/host-metrics.json index 7ba158a2cc..2fd9cee461 100644 --- a/test/mock/collector/grafana/provisioning/dashboards/host-metrics.json +++ b/test/mock/collector/grafana/provisioning/dashboards/host-metrics.json @@ -209,7 +209,7 @@ "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "{{nginx_conn_outcome}}", + "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false @@ -308,7 +308,7 @@ "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "Requests", + "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false diff --git a/test/mock/collector/grafana/provisioning/dashboards/nginx-dashboard.json b/test/mock/collector/grafana/provisioning/dashboards/nginx-dashboard.json index a9224370a8..1744513236 100644 --- a/test/mock/collector/grafana/provisioning/dashboards/nginx-dashboard.json +++ b/test/mock/collector/grafana/provisioning/dashboards/nginx-dashboard.json @@ -1,540 +1,440 @@ { "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] }, "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, "links": [], "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "id": 5, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { + { "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" + "type": "prometheus", + "uid": "otel-prometheus-scraper" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "nginx_http_response_status", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "HTTP Response Status", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ { - "color": "red", - "value": 80 + "datasource": { + "type": "prometheus", + "uid": "otel-prometheus-scraper" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "nginx_http_conn_count", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{nginx_conn_outcome}}", + "range": true, + "refId": "A", + "useBackend": false } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 0 + ], + "title": "HTTP Connections Count", + "type": "timeseries" }, - "id": 4, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { + { "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" + "type": "prometheus", + "uid": "otel-prometheus-scraper" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "nginx_connections_current", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "NGINX Connections Current", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ { - "color": "red", - "value": 80 + "datasource": { + "type": "prometheus", + "uid": "otel-prometheus-scraper" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "nginx_http_conn", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{nginx_conn_outcome}}", + "range": true, + "refId": "A", + "useBackend": false } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 8 + ], + "title": "HTTP Connections", + "type": "timeseries" }, - "id": 1, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { + { "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" + "type": "prometheus", + "uid": "otel-prometheus-scraper" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "nginx_http_requests", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "NGINX Requests Total", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ { - "color": "red", - "value": 80 + "datasource": { + "type": "prometheus", + "uid": "otel-prometheus-scraper" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "nginx_http_requests", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 8 - }, - "id": 3, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "maxHeight": 600, - "mode": "single", - "sort": "none" - } + ], + "title": "Total HTTP Requests", + "type": "timeseries" }, - "targets": [ - { + { "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" + "type": "prometheus", + "uid": "otel-prometheus-scraper" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "nginx_http_conn_count", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "NGINX Connections Current Count", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "insertNulls": false, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - { - "color": "red", - "value": 80 + "tooltip": { + "mode": "single", + "sort": "none" } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 16 - }, - "id": 2, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "maxHeight": 600, - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "otel-prometheus-scraper" }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "nginx_http_conn", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "NGINX Connection Totals", - "type": "timeseries" - } + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "otel-prometheus-scraper" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "nginx_http_response_status", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "HTTP Response Status", + "type": "timeseries" + } ], "refresh": "5s", "schemaVersion": 39, "tags": [], "templating": { - "list": [] + "list": [] }, "time": { - "from": "now-5m", - "to": "now" + "from": "now-5m", + "to": "now" }, "timepicker": {}, "timezone": "browser", "title": "NGINX OSS", "uid": "bdogpq9khs9hcb", - "version": 1, + "version": 6, "weekStart": "" - } +}