@@ -1759,6 +1759,52 @@ func TestQuerier_DetectedFields(t *testing.T) {
1759
1759
}
1760
1760
})
1761
1761
1762
+ t .Run ("returns detected fields with structured metadata from queried logs" , func (t * testing.T ) {
1763
+ store := newStoreMock ()
1764
+ store .On ("SelectLogs" , mock .Anything , mock .Anything ).
1765
+ Return (mockLogfmtStreamIterator (1 , 5 ), nil )
1766
+
1767
+ queryClient := newQueryClientMock ()
1768
+ queryClient .On ("Recv" ).
1769
+ Return (mockQueryResponse ([]logproto.Stream {mockLogfmtStreamWithStructuredMetadata (1 , 5 )}), nil )
1770
+
1771
+ ingesterClient := newQuerierClientMock ()
1772
+ ingesterClient .On ("Query" , mock .Anything , mock .Anything , mock .Anything ).
1773
+ Return (queryClient , nil )
1774
+
1775
+ querier , err := newQuerier (
1776
+ conf ,
1777
+ mockIngesterClientConfig (),
1778
+ newIngesterClientMockFactory (ingesterClient ),
1779
+ mockReadRingWithOneActiveIngester (),
1780
+ & mockDeleteGettter {},
1781
+ store , limits )
1782
+ require .NoError (t , err )
1783
+
1784
+ resp , err := querier .DetectedFields (ctx , & request )
1785
+ require .NoError (t , err )
1786
+
1787
+ detectedFields := resp .Fields
1788
+ // log lines come from querier_mock_test.go
1789
+ // message="line %d" count=%d fake=true bytes=%dMB duration=%dms percent=%f even=%t
1790
+ assert .Len (t , detectedFields , 9 )
1791
+ expectedCardinality := map [string ]uint64 {
1792
+ "variable" : 5 ,
1793
+ "constant" : 1 ,
1794
+ "message" : 5 ,
1795
+ "count" : 5 ,
1796
+ "fake" : 1 ,
1797
+ "bytes" : 5 ,
1798
+ "duration" : 5 ,
1799
+ "percent" : 5 ,
1800
+ "even" : 2 ,
1801
+ }
1802
+ for _ , d := range detectedFields {
1803
+ card := expectedCardinality [d .Label ]
1804
+ assert .Equal (t , card , d .Cardinality , "Expected cardinality mismatch for: %s" , d .Label )
1805
+ }
1806
+ })
1807
+
1762
1808
t .Run ("correctly identifies different field types" , func (t * testing.T ) {
1763
1809
store := newStoreMock ()
1764
1810
store .On ("SelectLogs" , mock .Anything , mock .Anything ).
@@ -1814,6 +1860,68 @@ func TestQuerier_DetectedFields(t *testing.T) {
1814
1860
assert .Equal (t , logproto .DetectedFieldFloat , floatField .Type )
1815
1861
assert .Equal (t , logproto .DetectedFieldBoolean , evenField .Type )
1816
1862
})
1863
+
1864
+ t .Run ("correctly identifies parser to use with logfmt and structured metadata" , func (t * testing.T ) {
1865
+ store := newStoreMock ()
1866
+ store .On ("SelectLogs" , mock .Anything , mock .Anything ).
1867
+ Return (mockLogfmtStreamIterator (1 , 2 ), nil )
1868
+
1869
+ queryClient := newQueryClientMock ()
1870
+ queryClient .On ("Recv" ).
1871
+ Return (mockQueryResponse ([]logproto.Stream {mockLogfmtStreamWithStructuredMetadata (1 , 2 )}), nil )
1872
+
1873
+ ingesterClient := newQuerierClientMock ()
1874
+ ingesterClient .On ("Query" , mock .Anything , mock .Anything , mock .Anything ).
1875
+ Return (queryClient , nil )
1876
+
1877
+ querier , err := newQuerier (
1878
+ conf ,
1879
+ mockIngesterClientConfig (),
1880
+ newIngesterClientMockFactory (ingesterClient ),
1881
+ mockReadRingWithOneActiveIngester (),
1882
+ & mockDeleteGettter {},
1883
+ store , limits )
1884
+ require .NoError (t , err )
1885
+
1886
+ resp , err := querier .DetectedFields (ctx , & request )
1887
+ require .NoError (t , err )
1888
+
1889
+ detectedFields := resp .Fields
1890
+ // log lines come from querier_mock_test.go
1891
+ // message="line %d" count=%d fake=true bytes=%dMB duration=%dms percent=%f even=%t
1892
+ assert .Len (t , detectedFields , 9 )
1893
+
1894
+ var messageField , countField , bytesField , durationField , floatField , evenField , constantField , variableField * logproto.DetectedField
1895
+ for _ , field := range detectedFields {
1896
+ switch field .Label {
1897
+ case "message" :
1898
+ messageField = field
1899
+ case "count" :
1900
+ countField = field
1901
+ case "bytes" :
1902
+ bytesField = field
1903
+ case "duration" :
1904
+ durationField = field
1905
+ case "percent" :
1906
+ floatField = field
1907
+ case "even" :
1908
+ evenField = field
1909
+ case "constant" :
1910
+ constantField = field
1911
+ case "variable" :
1912
+ variableField = field
1913
+ }
1914
+ }
1915
+
1916
+ assert .Equal (t , []string {"logfmt" }, messageField .Parsers )
1917
+ assert .Equal (t , []string {"logfmt" }, countField .Parsers )
1918
+ assert .Equal (t , []string {"logfmt" }, bytesField .Parsers )
1919
+ assert .Equal (t , []string {"logfmt" }, durationField .Parsers )
1920
+ assert .Equal (t , []string {"logfmt" }, floatField .Parsers )
1921
+ assert .Equal (t , []string {"logfmt" }, evenField .Parsers )
1922
+ assert .Equal (t , []string {"" }, constantField .Parsers )
1923
+ assert .Equal (t , []string {"" }, variableField .Parsers )
1924
+ })
1817
1925
}
1818
1926
1819
1927
func BenchmarkQuerierDetectedFields (b * testing.B ) {
0 commit comments