github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/logql/log/parser_hints_test.go (about)

     1  // uses log_test package to avoid circular dependency between log and logql package.
     2  package log_test
     3  
     4  import (
     5  	"testing"
     6  
     7  	"github.com/prometheus/prometheus/model/labels"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/grafana/loki/pkg/logql/syntax"
    11  )
    12  
    13  var (
    14  	jsonLine = []byte(`{
    15  	"remote_user": "foo",
    16  	"upstream_addr": "10.0.0.1:80",
    17  	"protocol": "HTTP/2.0",
    18      "cluster": "us-east-west",
    19  	"request": {
    20  		"time": "30.001",
    21  		"method": "POST",
    22  		"host": "foo.grafana.net",
    23  		"uri": "/rpc/v2/stage",
    24  		"size": "101"
    25  	},
    26  	"response": {
    27  		"status": 204,
    28  		"latency_seconds": "30.001"
    29  	}
    30  }`)
    31  
    32  	packedLine = []byte(`{
    33  		"remote_user": "foo",
    34  		"upstream_addr": "10.0.0.1:80",
    35  		"protocol": "HTTP/2.0",
    36  		"cluster": "us-east-west",
    37  		"_entry":"foo"
    38  	}`)
    39  
    40  	logfmtLine = []byte(`ts=2021-02-02T14:35:05.983992774Z caller=spanlogger.go:79 org_id=3677 traceID=2e5c7234b8640997 Ingester.TotalReached=15 Ingester.TotalChunksMatched=0 Ingester.TotalBatches=0`)
    41  )
    42  
    43  func Test_ParserHints(t *testing.T) {
    44  	lbs := labels.Labels{{Name: "app", Value: "nginx"}, {Name: "cluster", Value: "us-central-west"}}
    45  
    46  	t.Parallel()
    47  	for _, tt := range []struct {
    48  		expr      string
    49  		line      []byte
    50  		expectOk  bool
    51  		expectVal float64
    52  		expectLbs string
    53  	}{
    54  		{
    55  			`rate({app="nginx"} | json | response_status = 204 [1m])`,
    56  			jsonLine,
    57  			true,
    58  			1.0,
    59  			`{app="nginx", cluster="us-central-west", cluster_extracted="us-east-west", protocol="HTTP/2.0", remote_user="foo", request_host="foo.grafana.net", request_method="POST", request_size="101", request_time="30.001", request_uri="/rpc/v2/stage", response_latency_seconds="30.001", response_status="204", upstream_addr="10.0.0.1:80"}`,
    60  		},
    61  		{
    62  			`sum without (request_host,app,cluster) (rate({app="nginx"} | json | __error__="" | response_status = 204 [1m]))`,
    63  			jsonLine,
    64  			true,
    65  			1.0,
    66  			`{cluster_extracted="us-east-west", protocol="HTTP/2.0", remote_user="foo", request_method="POST", request_size="101", request_time="30.001", request_uri="/rpc/v2/stage", response_latency_seconds="30.001", response_status="204", upstream_addr="10.0.0.1:80"}`,
    67  		},
    68  		{
    69  			`sum by (request_host,app) (rate({app="nginx"} | json | __error__="" | response_status = 204 [1m]))`,
    70  			jsonLine,
    71  			true,
    72  			1.0,
    73  			`{app="nginx", request_host="foo.grafana.net"}`,
    74  		},
    75  		{
    76  			`sum(rate({app="nginx"} | json | __error__="" | response_status = 204 [1m]))`,
    77  			jsonLine,
    78  			true,
    79  			1.0,
    80  			`{}`,
    81  		},
    82  		{
    83  			`sum(rate({app="nginx"} | json [1m]))`,
    84  			jsonLine,
    85  			true,
    86  			1.0,
    87  			`{}`,
    88  		},
    89  		{
    90  			`sum(rate({app="nginx"} | json | unwrap response_latency_seconds [1m]))`,
    91  			jsonLine,
    92  			true,
    93  			30.001,
    94  			`{}`,
    95  		},
    96  		{
    97  			`sum(rate({app="nginx"} | json | response_status = 204 | unwrap response_latency_seconds [1m]))`,
    98  			jsonLine,
    99  			true,
   100  			30.001,
   101  			`{}`,
   102  		},
   103  		{
   104  			`sum by (request_host,app)(rate({app="nginx"} | json | response_status = 204 and  remote_user = "foo" | unwrap response_latency_seconds [1m]))`,
   105  			jsonLine,
   106  			true,
   107  			30.001,
   108  			`{app="nginx", request_host="foo.grafana.net"}`,
   109  		},
   110  		{
   111  			`rate({app="nginx"} | json | response_status = 204 | unwrap response_latency_seconds [1m])`,
   112  			jsonLine,
   113  			true,
   114  			30.001,
   115  			`{app="nginx", cluster="us-central-west", cluster_extracted="us-east-west", protocol="HTTP/2.0", remote_user="foo", request_host="foo.grafana.net", request_method="POST", request_size="101", request_time="30.001", request_uri="/rpc/v2/stage", response_status="204", upstream_addr="10.0.0.1:80"}`,
   116  		},
   117  		{
   118  			`sum without (request_host,app,cluster)(rate({app="nginx"} | json | response_status = 204 | unwrap response_latency_seconds [1m]))`,
   119  			jsonLine,
   120  			true,
   121  			30.001,
   122  			`{cluster_extracted="us-east-west", protocol="HTTP/2.0", remote_user="foo", request_method="POST", request_size="101", request_time="30.001", request_uri="/rpc/v2/stage", response_status="204", upstream_addr="10.0.0.1:80"}`,
   123  		},
   124  		{
   125  			`sum(rate({app="nginx"} | logfmt | org_id=3677 | unwrap Ingester_TotalReached[1m]))`,
   126  			logfmtLine,
   127  			true,
   128  			15.0,
   129  			`{}`,
   130  		},
   131  		{
   132  			`sum by (org_id,app) (rate({app="nginx"} | logfmt | org_id=3677 | unwrap Ingester_TotalReached[1m]))`,
   133  			logfmtLine,
   134  			true,
   135  			15.0,
   136  			`{app="nginx", org_id="3677"}`,
   137  		},
   138  		{
   139  			`rate({app="nginx"} | logfmt | org_id=3677 | unwrap Ingester_TotalReached[1m])`,
   140  			logfmtLine,
   141  			true,
   142  			15.0,
   143  			`{Ingester_TotalBatches="0", Ingester_TotalChunksMatched="0", app="nginx", caller="spanlogger.go:79", cluster="us-central-west", org_id="3677", traceID="2e5c7234b8640997", ts="2021-02-02T14:35:05.983992774Z"}`,
   144  		},
   145  		{
   146  			`sum without (org_id,app,cluster)(rate({app="nginx"} | logfmt | org_id=3677 | unwrap Ingester_TotalReached[1m]))`,
   147  			logfmtLine,
   148  			true,
   149  			15.0,
   150  			`{Ingester_TotalBatches="0", Ingester_TotalChunksMatched="0", caller="spanlogger.go:79", traceID="2e5c7234b8640997", ts="2021-02-02T14:35:05.983992774Z"}`,
   151  		},
   152  		{
   153  			`sum(rate({app="nginx"} | json | remote_user="foo" [1m]))`,
   154  			jsonLine,
   155  			true,
   156  			1.0,
   157  			`{}`,
   158  		},
   159  		{
   160  			`sum(rate({app="nginx"} | json | nonexistant_field="foo" [1m]))`,
   161  			jsonLine,
   162  			false,
   163  			0,
   164  			``,
   165  		},
   166  		{
   167  			`absent_over_time({app="nginx"} | json [1m])`,
   168  			jsonLine,
   169  			true,
   170  			1.0,
   171  			`{}`,
   172  		},
   173  		{
   174  			`absent_over_time({app="nginx"} | json | nonexistant_field="foo" [1m])`,
   175  			jsonLine,
   176  			false,
   177  			0,
   178  			``,
   179  		},
   180  		{
   181  			`absent_over_time({app="nginx"} | json | remote_user="foo" [1m])`,
   182  			jsonLine,
   183  			true,
   184  			1.0,
   185  			`{}`,
   186  		},
   187  		{
   188  			`sum by (cluster_extracted)(count_over_time({app="nginx"} | json | cluster_extracted="us-east-west" [1m]))`,
   189  			jsonLine,
   190  			true,
   191  			1.0,
   192  			`{cluster_extracted="us-east-west"}`,
   193  		},
   194  		{
   195  			`sum by (cluster_extracted)(count_over_time({app="nginx"} | unpack | cluster_extracted="us-east-west" [1m]))`,
   196  			packedLine,
   197  			true,
   198  			1.0,
   199  			`{cluster_extracted="us-east-west"}`,
   200  		},
   201  		{
   202  			`sum by (cluster_extracted)(count_over_time({app="nginx"} | unpack[1m]))`,
   203  			packedLine,
   204  			true,
   205  			1.0,
   206  			`{cluster_extracted="us-east-west"}`,
   207  		},
   208  		{
   209  			`sum(rate({app="nginx"} | unpack | nonexistant_field="foo" [1m]))`,
   210  			packedLine,
   211  			false,
   212  			0,
   213  			``,
   214  		},
   215  	} {
   216  		tt := tt
   217  		t.Run(tt.expr, func(t *testing.T) {
   218  			t.Parallel()
   219  			expr, err := syntax.ParseSampleExpr(tt.expr)
   220  			require.NoError(t, err)
   221  
   222  			ex, err := expr.Extractor()
   223  			require.NoError(t, err)
   224  			v, lbsRes, ok := ex.ForStream(lbs).Process(0, append([]byte{}, tt.line...))
   225  			var lbsResString string
   226  			if lbsRes != nil {
   227  				lbsResString = lbsRes.String()
   228  			}
   229  			require.Equal(t, tt.expectOk, ok)
   230  			require.Equal(t, tt.expectVal, v)
   231  			require.Equal(t, tt.expectLbs, lbsResString)
   232  		})
   233  	}
   234  }