From 5d4d02d679eecbdf01f01d5172dd2f74c10f09f5 Mon Sep 17 00:00:00 2001 From: loser <1711788888@qq.com> Date: Wed, 7 Sep 2022 17:17:11 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E8=BF=81=E7=A7=BB=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 211 +- README.md | 12 +- go.mod | 20 + loki/batch.go | 107 + loki/batch_test.go | 139 + loki/client.go | 403 ++ loki/client_test.go | 356 ++ loki/config.go | 109 + loki/config_test.go | 94 + pkg/backoff/backoff.go | 117 + pkg/helpers/config.go | 18 + pkg/helpers/logerror.go | 13 + pkg/helpers/math.go | 9 + pkg/httputil/http.go | 164 + pkg/labelutil/label.go | 99 + pkg/logproto/extensions.go | 23 + pkg/logproto/logproto.pb.go | 8031 +++++++++++++++++++++++++++++++++ pkg/logproto/logproto.proto | 166 + pkg/logproto/timestamp.go | 106 + pkg/logproto/types.go | 475 ++ pkg/logproto/types_test.go | 111 + pkg/metric/counters.go | 117 + pkg/metric/counters_test.go | 140 + pkg/metric/gauges.go | 136 + pkg/metric/gauges_test.go | 40 + pkg/metric/histograms.go | 79 + pkg/metric/histograms_test.go | 38 + pkg/metric/metricvec.go | 82 + pkg/urlutil/url.go | 59 + 29 files changed, 11431 insertions(+), 43 deletions(-) create mode 100644 go.mod create mode 100644 loki/batch.go create mode 100644 loki/batch_test.go create mode 100644 loki/client.go create mode 100644 loki/client_test.go create mode 100644 loki/config.go create mode 100644 loki/config_test.go create mode 100644 pkg/backoff/backoff.go create mode 100644 pkg/helpers/config.go create mode 100644 pkg/helpers/logerror.go create mode 100644 pkg/helpers/math.go create mode 100644 pkg/httputil/http.go create mode 100644 pkg/labelutil/label.go create mode 100644 pkg/logproto/extensions.go create mode 100644 pkg/logproto/logproto.pb.go create mode 100644 pkg/logproto/logproto.proto create mode 100644 pkg/logproto/timestamp.go create mode 100644 pkg/logproto/types.go create mode 100644 pkg/logproto/types_test.go create mode 100644 pkg/metric/counters.go create mode 100644 pkg/metric/counters_test.go create mode 100644 pkg/metric/gauges.go create mode 100644 pkg/metric/gauges_test.go create mode 100644 pkg/metric/histograms.go create mode 100644 pkg/metric/histograms_test.go create mode 100644 pkg/metric/metricvec.go create mode 100644 pkg/urlutil/url.go diff --git a/LICENSE b/LICENSE index 137069b..d645695 100644 --- a/LICENSE +++ b/LICENSE @@ -1,73 +1,202 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -1. Definitions. + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + 1. Definitions. -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. - (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: - (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and - (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and - (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and - You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. -END OF TERMS AND CONDITIONS + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. -APPENDIX: How to apply the Apache License to your work. + END OF TERMS AND CONDITIONS -To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + APPENDIX: How to apply the Apache License to your work. -Copyright [yyyy] [name of copyright owner] + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -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 + Copyright [yyyy] [name of copyright owner] -http://www.apache.org/licenses/LICENSE-2.0 + 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 -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. + 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. diff --git a/README.md b/README.md index bd9528b..62a6d41 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ -# loki-client-go +# Loki Go client (Experimental. DO NOT USE IT) -loki-client-go \ No newline at end of file +An HTTP client to send logs to Loki server + +## Install + +## Usage + +## License + +Apache License 2.0, see [LICENSE](LICENSE). diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..37bbbb9 --- /dev/null +++ b/go.mod @@ -0,0 +1,20 @@ +module git.echol.cn/loser/loki-client-go + +go 1.15 + +require ( + github.com/blang/semver v3.5.1+incompatible + github.com/go-kit/kit v0.10.0 + github.com/gogo/protobuf v1.3.1 + github.com/golang/snappy v0.0.2 + github.com/json-iterator/go v1.1.11 + github.com/mitchellh/mapstructure v1.2.2 + github.com/opentracing/opentracing-go v1.2.0 + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/common v0.30.0 + github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24 + github.com/stretchr/testify v1.6.1 + google.golang.org/grpc v1.32.0 + gopkg.in/yaml.v2 v2.4.0 +) diff --git a/loki/batch.go b/loki/batch.go new file mode 100644 index 0000000..e6cedad --- /dev/null +++ b/loki/batch.go @@ -0,0 +1,107 @@ +package loki + +import ( + "time" + + "github.com/gogo/protobuf/proto" + "github.com/golang/snappy" + json "github.com/json-iterator/go" + + "github.com/lixh00/loki-client-go/pkg/logproto" +) + +// batch holds pending log streams waiting to be sent to Loki, and it's used +// to reduce the number of push requests to Loki aggregating multiple log streams +// and entries in a single batch request. In case of multi-tenant Promtail, log +// streams for each tenant are stored in a dedicated batch. +type batch struct { + streams map[string]*logproto.Stream + bytes int + createdAt time.Time +} + +func newBatch(entries ...entry) *batch { + b := &batch{ + streams: map[string]*logproto.Stream{}, + bytes: 0, + createdAt: time.Now(), + } + + // Add entries to the batch + for _, entry := range entries { + b.add(entry) + } + + return b +} + +// add an entry to the batch +func (b *batch) add(entry entry) { + b.bytes += len(entry.Line) + + // Append the entry to an already existing stream (if any) + labels := entry.labels.String() + if stream, ok := b.streams[labels]; ok { + stream.Entries = append(stream.Entries, entry.Entry) + return + } + + // Add the entry as a new stream + b.streams[labels] = &logproto.Stream{ + Labels: labels, + Entries: []logproto.Entry{entry.Entry}, + } +} + +// sizeBytes returns the current batch size in bytes +func (b *batch) sizeBytes() int { + return b.bytes +} + +// sizeBytesAfter returns the size of the batch after the input entry +// will be added to the batch itself +func (b *batch) sizeBytesAfter(entry entry) int { + return b.bytes + len(entry.Line) +} + +// age of the batch since its creation +func (b *batch) age() time.Duration { + return time.Since(b.createdAt) +} + +// encode the batch as snappy-compressed push request, and returns +// the encoded bytes and the number of encoded entries +func (b *batch) encode() ([]byte, int, error) { + req, entriesCount := b.createPushRequest() + buf, err := proto.Marshal(req) + if err != nil { + return nil, 0, err + } + buf = snappy.Encode(nil, buf) + return buf, entriesCount, nil +} + +// encode the batch as json push request, and returns +// the encoded bytes and the number of encoded entries +func (b *batch) encodeJSON() ([]byte, int, error) { + req, entriesCount := b.createPushRequest() + buf, err := json.Marshal(req) + if err != nil { + return nil, 0, err + } + return buf, entriesCount, nil +} + +// creates push request and returns it, together with number of entries +func (b *batch) createPushRequest() (*logproto.PushRequest, int) { + req := logproto.PushRequest{ + Streams: make([]logproto.Stream, 0, len(b.streams)), + } + + entriesCount := 0 + for _, stream := range b.streams { + req.Streams = append(req.Streams, *stream) + entriesCount += len(stream.Entries) + } + return &req, entriesCount +} diff --git a/loki/batch_test.go b/loki/batch_test.go new file mode 100644 index 0000000..f10b050 --- /dev/null +++ b/loki/batch_test.go @@ -0,0 +1,139 @@ +package loki + +import ( + "fmt" + "testing" + "time" + + "github.com/prometheus/common/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/lixh00/loki-client-go/pkg/logproto" +) + +func TestBatch_add(t *testing.T) { + t.Parallel() + + tests := map[string]struct { + inputEntries []entry + expectedSizeBytes int + }{ + "empty batch": { + inputEntries: []entry{}, + expectedSizeBytes: 0, + }, + "single stream with single log entry": { + inputEntries: []entry{ + {"tenant", model.LabelSet{}, logEntries[0].Entry}, + }, + expectedSizeBytes: len(logEntries[0].Entry.Line), + }, + "single stream with multiple log entries": { + inputEntries: []entry{ + {"tenant", model.LabelSet{}, logEntries[0].Entry}, + {"tenant", model.LabelSet{}, logEntries[1].Entry}, + }, + expectedSizeBytes: len(logEntries[0].Entry.Line) + len(logEntries[1].Entry.Line), + }, + "multiple streams with multiple log entries": { + inputEntries: []entry{ + {"tenant", model.LabelSet{"type": "a"}, logEntries[0].Entry}, + {"tenant", model.LabelSet{"type": "a"}, logEntries[1].Entry}, + {"tenant", model.LabelSet{"type": "b"}, logEntries[2].Entry}, + }, + expectedSizeBytes: len(logEntries[0].Entry.Line) + len(logEntries[1].Entry.Line) + len(logEntries[2].Entry.Line), + }, + } + + for testName, testData := range tests { + testData := testData + + t.Run(testName, func(t *testing.T) { + b := newBatch() + + for _, entry := range testData.inputEntries { + b.add(entry) + } + + assert.Equal(t, testData.expectedSizeBytes, b.sizeBytes()) + }) + } +} + +func TestBatch_encode(t *testing.T) { + t.Parallel() + + tests := map[string]struct { + inputBatch *batch + expectedEntriesCount int + }{ + "empty batch": { + inputBatch: newBatch(), + expectedEntriesCount: 0, + }, + "single stream with single log entry": { + inputBatch: newBatch( + entry{"tenant", model.LabelSet{}, logEntries[0].Entry}, + ), + expectedEntriesCount: 1, + }, + "single stream with multiple log entries": { + inputBatch: newBatch( + entry{"tenant", model.LabelSet{}, logEntries[0].Entry}, + entry{"tenant", model.LabelSet{}, logEntries[1].Entry}, + ), + expectedEntriesCount: 2, + }, + "multiple streams with multiple log entries": { + inputBatch: newBatch( + entry{"tenant", model.LabelSet{"type": "a"}, logEntries[0].Entry}, + entry{"tenant", model.LabelSet{"type": "a"}, logEntries[1].Entry}, + entry{"tenant", model.LabelSet{"type": "b"}, logEntries[2].Entry}, + ), + expectedEntriesCount: 3, + }, + } + + for testName, testData := range tests { + testData := testData + + t.Run(testName, func(t *testing.T) { + t.Parallel() + + _, entriesCount, err := testData.inputBatch.encode() + require.NoError(t, err) + assert.Equal(t, testData.expectedEntriesCount, entriesCount) + }) + } +} + +func TestHashCollisions(t *testing.T) { + b := newBatch() + + ls1 := model.LabelSet{"app": "l", "uniq0": "0", "uniq1": "1"} + ls2 := model.LabelSet{"app": "m", "uniq0": "1", "uniq1": "1"} + + require.False(t, ls1.Equal(ls2)) + require.Equal(t, ls1.FastFingerprint(), ls2.FastFingerprint()) + + const entriesPerLabel = 10 + + for i := 0; i < entriesPerLabel; i++ { + b.add(entry{labels: ls1, Entry: logproto.Entry{Timestamp: time.Now(), Line: fmt.Sprintf("line %d", i)}}) + b.add(entry{labels: ls2, Entry: logproto.Entry{Timestamp: time.Now(), Line: fmt.Sprintf("line %d", i)}}) + } + + // make sure that colliding labels are stored properly as independent streams + req, entries := b.createPushRequest() + assert.Len(t, req.Streams, 2) + assert.Equal(t, 2*entriesPerLabel, entries) + + if req.Streams[0].Labels == ls1.String() { + assert.Equal(t, ls1.String(), req.Streams[0].Labels) + assert.Equal(t, ls2.String(), req.Streams[1].Labels) + } else { + assert.Equal(t, ls2.String(), req.Streams[0].Labels) + assert.Equal(t, ls1.String(), req.Streams[1].Labels) + } +} diff --git a/loki/client.go b/loki/client.go new file mode 100644 index 0000000..4154c4d --- /dev/null +++ b/loki/client.go @@ -0,0 +1,403 @@ +package loki + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "io" + "net/http" + "os" + "strconv" + "sync" + "time" + + "github.com/lixh00/loki-client-go/pkg/backoff" + "github.com/prometheus/prometheus/promql/parser" + + "github.com/lixh00/loki-client-go/pkg/metric" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + "github.com/prometheus/common/version" + + "github.com/lixh00/loki-client-go/pkg/helpers" + "github.com/lixh00/loki-client-go/pkg/logproto" +) + +const ( + protoContentType = "application/x-protobuf" + JSONContentType = "application/json" + maxErrMsgLen = 1024 + + // Label reserved to override the tenant ID while processing + // pipeline stages + ReservedLabelTenantID = "__tenant_id__" + + LatencyLabel = "filename" + HostLabel = "host" +) + +var ( + encodedBytes = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "promtail", + Name: "encoded_bytes_total", + Help: "Number of bytes encoded and ready to send.", + }, []string{HostLabel}) + sentBytes = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "promtail", + Name: "sent_bytes_total", + Help: "Number of bytes sent.", + }, []string{HostLabel}) + droppedBytes = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "promtail", + Name: "dropped_bytes_total", + Help: "Number of bytes dropped because failed to be sent to the ingester after all retries.", + }, []string{HostLabel}) + sentEntries = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "promtail", + Name: "sent_entries_total", + Help: "Number of log entries sent to the ingester.", + }, []string{HostLabel}) + droppedEntries = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "promtail", + Name: "dropped_entries_total", + Help: "Number of log entries dropped because failed to be sent to the ingester after all retries.", + }, []string{HostLabel}) + requestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "promtail", + Name: "request_duration_seconds", + Help: "Duration of send requests.", + }, []string{"status_code", HostLabel}) + batchRetries = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: "promtail", + Name: "batch_retries_total", + Help: "Number of times batches has had to be retried.", + }, []string{HostLabel}) + streamLag *metric.Gauges + + countersWithHost = []*prometheus.CounterVec{ + encodedBytes, sentBytes, droppedBytes, sentEntries, droppedEntries, + } + + UserAgent = fmt.Sprintf("promtail/%s", version.Version) +) + +func init() { + prometheus.MustRegister(encodedBytes) + prometheus.MustRegister(sentBytes) + prometheus.MustRegister(droppedBytes) + prometheus.MustRegister(sentEntries) + prometheus.MustRegister(droppedEntries) + prometheus.MustRegister(requestDuration) + prometheus.MustRegister(batchRetries) + var err error + streamLag, err = metric.NewGauges("promtail_stream_lag_seconds", + "Difference between current time and last batch timestamp for successful sends", + metric.GaugeConfig{Action: "set"}, + int64(1*time.Minute.Seconds()), // This strips out files which update slowly and reduces noise in this metric. + ) + if err != nil { + panic(err) + } + prometheus.MustRegister(streamLag) +} + +// Client for pushing logs in snappy-compressed protos over HTTP. +type Client struct { + logger log.Logger + cfg Config + client *http.Client + quit chan struct{} + once sync.Once + entries chan entry + wg sync.WaitGroup + + externalLabels model.LabelSet +} + +type entry struct { + tenantID string + labels model.LabelSet + logproto.Entry +} + +// New makes a new Client from config +func New(cfg Config) (*Client, error) { + logger := level.NewFilter(log.NewLogfmtLogger(os.Stdout), level.AllowWarn()) + return NewWithLogger(cfg, logger) +} + +// NewWithDefault creates a new client with default configuration. +func NewWithDefault(url string) (*Client, error) { + cfg, err := NewDefaultConfig(url) + if err != nil { + return nil, err + } + return New(cfg) +} + +// NewWithLogger makes a new Client from a logger and a config +func NewWithLogger(cfg Config, logger log.Logger) (*Client, error) { + if cfg.URL.URL == nil { + return nil, errors.New("client needs target URL") + } + + c := &Client{ + logger: log.With(logger, "component", "client", "host", cfg.URL.Host), + cfg: cfg, + quit: make(chan struct{}), + entries: make(chan entry), + + externalLabels: cfg.ExternalLabels.LabelSet, + } + + err := cfg.Client.Validate() + if err != nil { + return nil, err + } + + c.client, err = config.NewClientFromConfig(cfg.Client, "promtail", config.WithKeepAlivesDisabled(), config.WithHTTP2Disabled()) + if err != nil { + return nil, err + } + + c.client.Timeout = cfg.Timeout + + // Initialize counters to 0 so the metrics are exported before the first + // occurrence of incrementing to avoid missing metrics. + for _, counter := range countersWithHost { + counter.WithLabelValues(c.cfg.URL.Host).Add(0) + } + + c.wg.Add(1) + go c.run() + return c, nil +} + +func (c *Client) run() { + batches := map[string]*batch{} + + // Given the client handles multiple batches (1 per tenant) and each batch + // can be created at a different point in time, we look for batches whose + // max wait time has been reached every 10 times per BatchWait, so that the + // maximum delay we have sending batches is 10% of the max waiting time. + // We apply a cap of 10ms to the ticker, to avoid too frequent checks in + // case the BatchWait is very low. + minWaitCheckFrequency := 10 * time.Millisecond + maxWaitCheckFrequency := c.cfg.BatchWait / 10 + if maxWaitCheckFrequency < minWaitCheckFrequency { + maxWaitCheckFrequency = minWaitCheckFrequency + } + + maxWaitCheck := time.NewTicker(maxWaitCheckFrequency) + + defer func() { + // Send all pending batches + for tenantID, batch := range batches { + c.sendBatch(tenantID, batch) + } + + c.wg.Done() + }() + + for { + select { + case <-c.quit: + return + + case e := <-c.entries: + batch, ok := batches[e.tenantID] + + // If the batch doesn't exist yet, we create a new one with the entry + if !ok { + batches[e.tenantID] = newBatch(e) + break + } + + // If adding the entry to the batch will increase the size over the max + // size allowed, we do send the current batch and then create a new one + if batch.sizeBytesAfter(e) > c.cfg.BatchSize { + c.sendBatch(e.tenantID, batch) + + batches[e.tenantID] = newBatch(e) + break + } + + // The max size of the batch isn't reached, so we can add the entry + batch.add(e) + + case <-maxWaitCheck.C: + // Send all batches whose max wait time has been reached + for tenantID, batch := range batches { + if batch.age() < c.cfg.BatchWait { + continue + } + + c.sendBatch(tenantID, batch) + delete(batches, tenantID) + } + } + } +} + +func (c *Client) sendBatch(tenantID string, batch *batch) { + var ( + err error + buf []byte + entriesCount int + ) + if c.cfg.EncodeJson { + buf, entriesCount, err = batch.encodeJSON() + } else { + buf, entriesCount, err = batch.encode() + } + + if err != nil { + level.Error(c.logger).Log("msg", "error encoding batch", "error", err) + return + } + bufBytes := float64(len(buf)) + encodedBytes.WithLabelValues(c.cfg.URL.Host).Add(bufBytes) + + ctx := context.Background() + backoff := backoff.New(ctx, c.cfg.BackoffConfig) + var status int + for backoff.Ongoing() { + start := time.Now() + status, err = c.send(ctx, tenantID, buf) + requestDuration.WithLabelValues(strconv.Itoa(status), c.cfg.URL.Host).Observe(time.Since(start).Seconds()) + + if err == nil { + sentBytes.WithLabelValues(c.cfg.URL.Host).Add(bufBytes) + sentEntries.WithLabelValues(c.cfg.URL.Host).Add(float64(entriesCount)) + for _, s := range batch.streams { + lbls, err := parser.ParseMetric(s.Labels) + if err != nil { + // is this possible? + level.Warn(c.logger).Log("msg", "error converting stream label string to label.Labels, cannot update lagging metric", "error", err) + return + } + var lblSet model.LabelSet + for i := range lbls { + if lbls[i].Name == LatencyLabel { + lblSet = model.LabelSet{ + model.LabelName(HostLabel): model.LabelValue(c.cfg.URL.Host), + model.LabelName(LatencyLabel): model.LabelValue(lbls[i].Value), + } + } + } + if lblSet != nil { + streamLag.With(lblSet).Set(time.Since(s.Entries[len(s.Entries)-1].Timestamp).Seconds()) + } + } + return + } + + // Only retry 429s, 500s and connection-level errors. + if status > 0 && status != 429 && status/100 != 5 { + break + } + + level.Warn(c.logger).Log("msg", "error sending batch, will retry", "status", status, "error", err) + batchRetries.WithLabelValues(c.cfg.URL.Host).Inc() + backoff.Wait() + } + + if err != nil { + level.Error(c.logger).Log("msg", "final error sending batch", "status", status, "error", err) + droppedBytes.WithLabelValues(c.cfg.URL.Host).Add(bufBytes) + droppedEntries.WithLabelValues(c.cfg.URL.Host).Add(float64(entriesCount)) + } +} + +func (c *Client) send(ctx context.Context, tenantID string, buf []byte) (int, error) { + ctx, cancel := context.WithTimeout(ctx, c.cfg.Timeout) + defer cancel() + req, err := http.NewRequest("POST", c.cfg.URL.String(), bytes.NewReader(buf)) + if err != nil { + return -1, err + } + req = req.WithContext(ctx) + req.Header.Set("Content-Type", protoContentType) + if c.cfg.EncodeJson { + req.Header.Set("Content-Type", JSONContentType) + } + req.Header.Set("User-Agent", UserAgent) + + // If the tenant ID is not empty promtail is running in multi-tenant mode, so + // we should send it to Loki + if tenantID != "" { + req.Header.Set("X-Scope-OrgID", tenantID) + } + + resp, err := c.client.Do(req) + if err != nil { + return -1, err + } + defer helpers.LogError(c.logger, "closing response body", resp.Body.Close) + + if resp.StatusCode/100 != 2 { + scanner := bufio.NewScanner(io.LimitReader(resp.Body, maxErrMsgLen)) + line := "" + if scanner.Scan() { + line = scanner.Text() + } + err = fmt.Errorf("server returned HTTP status %s (%d): %s", resp.Status, resp.StatusCode, line) + } + return resp.StatusCode, err +} + +func (c *Client) getTenantID(labels model.LabelSet) string { + // Check if it has been overridden while processing the pipeline stages + if value, ok := labels[ReservedLabelTenantID]; ok { + return string(value) + } + + // Check if has been specified in the config + if c.cfg.TenantID != "" { + return c.cfg.TenantID + } + + // Defaults to an empty string, which means the X-Scope-OrgID header + // will not be sent + return "" +} + +// Stop the client. +func (c *Client) Stop() { + c.once.Do(func() { close(c.quit) }) + c.wg.Wait() +} + +// Handle implement EntryHandler; adds a new line to the next batch; send is async. +func (c *Client) Handle(ls model.LabelSet, t time.Time, s string) error { + if len(c.externalLabels) > 0 { + ls = c.externalLabels.Merge(ls) + } + + // Get the tenant ID in case it has been overridden while processing + // the pipeline stages, then remove the special label + tenantID := c.getTenantID(ls) + if _, ok := ls[ReservedLabelTenantID]; ok { + // Clone the label set to not manipulate the input one + ls = ls.Clone() + delete(ls, ReservedLabelTenantID) + } + + c.entries <- entry{tenantID, ls, logproto.Entry{ + Timestamp: t, + Line: s, + }} + return nil +} + +func (c *Client) UnregisterLatencyMetric(labels model.LabelSet) { + labels[HostLabel] = model.LabelValue(c.cfg.URL.Host) + streamLag.Delete(labels) +} diff --git a/loki/client_test.go b/loki/client_test.go new file mode 100644 index 0000000..ce5b0a4 --- /dev/null +++ b/loki/client_test.go @@ -0,0 +1,356 @@ +package loki + +import ( + "io/ioutil" + "math" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/go-kit/kit/log" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/lixh00/loki-client-go/pkg/backoff" + "github.com/lixh00/loki-client-go/pkg/httputil" + "github.com/lixh00/loki-client-go/pkg/labelutil" + "github.com/lixh00/loki-client-go/pkg/urlutil" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + + "github.com/lixh00/loki-client-go/pkg/logproto" +) + +var logEntries = []entry{ + {labels: model.LabelSet{}, Entry: logproto.Entry{Timestamp: time.Unix(1, 0).UTC(), Line: "line1"}}, + {labels: model.LabelSet{}, Entry: logproto.Entry{Timestamp: time.Unix(2, 0).UTC(), Line: "line2"}}, + {labels: model.LabelSet{}, Entry: logproto.Entry{Timestamp: time.Unix(3, 0).UTC(), Line: "line3"}}, + {labels: model.LabelSet{"__tenant_id__": "tenant-1"}, Entry: logproto.Entry{Timestamp: time.Unix(4, 0).UTC(), Line: "line4"}}, + {labels: model.LabelSet{"__tenant_id__": "tenant-1"}, Entry: logproto.Entry{Timestamp: time.Unix(5, 0).UTC(), Line: "line5"}}, + {labels: model.LabelSet{"__tenant_id__": "tenant-2"}, Entry: logproto.Entry{Timestamp: time.Unix(6, 0).UTC(), Line: "line6"}}, +} + +type receivedReq struct { + tenantID string + pushReq logproto.PushRequest +} + +func TestClient_Handle(t *testing.T) { + tests := map[string]struct { + clientBatchSize int + clientBatchWait time.Duration + clientMaxRetries int + clientTenantID string + serverResponseStatus int + inputEntries []entry + inputDelay time.Duration + expectedReqs []receivedReq + expectedMetrics string + }{ + "batch log entries together until the batch size is reached": { + clientBatchSize: 10, + clientBatchWait: 100 * time.Millisecond, + clientMaxRetries: 3, + serverResponseStatus: 200, + inputEntries: []entry{logEntries[0], logEntries[1], logEntries[2]}, + expectedReqs: []receivedReq{ + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry, logEntries[1].Entry}}}}, + }, + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[2].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 3.0 + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 0 + `, + }, + "batch log entries together until the batch wait time is reached": { + clientBatchSize: 10, + clientBatchWait: 100 * time.Millisecond, + clientMaxRetries: 3, + serverResponseStatus: 200, + inputEntries: []entry{logEntries[0], logEntries[1]}, + inputDelay: 110 * time.Millisecond, + expectedReqs: []receivedReq{ + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[1].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 2.0 + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 0 + `, + }, + "retry send a batch up to backoff's max retries in case the server responds with a 5xx": { + clientBatchSize: 10, + clientBatchWait: 10 * time.Millisecond, + clientMaxRetries: 3, + serverResponseStatus: 500, + inputEntries: []entry{logEntries[0]}, + expectedReqs: []receivedReq{ + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 1.0 + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 0 + `, + }, + "do not retry send a batch in case the server responds with a 4xx": { + clientBatchSize: 10, + clientBatchWait: 10 * time.Millisecond, + clientMaxRetries: 3, + serverResponseStatus: 400, + inputEntries: []entry{logEntries[0]}, + expectedReqs: []receivedReq{ + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 1.0 + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 0 + `, + }, + "do retry sending a batch in case the server responds with a 429": { + clientBatchSize: 10, + clientBatchWait: 10 * time.Millisecond, + clientMaxRetries: 3, + serverResponseStatus: 429, + inputEntries: []entry{logEntries[0]}, + expectedReqs: []receivedReq{ + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + { + tenantID: "", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 1.0 + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 0 + `, + }, + "batch log entries together honoring the client tenant ID": { + clientBatchSize: 100, + clientBatchWait: 100 * time.Millisecond, + clientMaxRetries: 3, + clientTenantID: "tenant-default", + serverResponseStatus: 200, + inputEntries: []entry{logEntries[0], logEntries[1]}, + expectedReqs: []receivedReq{ + { + tenantID: "tenant-default", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry, logEntries[1].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 2.0 + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 0 + `, + }, + "batch log entries together honoring the tenant ID overridden while processing the pipeline stages": { + clientBatchSize: 100, + clientBatchWait: 100 * time.Millisecond, + clientMaxRetries: 3, + clientTenantID: "tenant-default", + serverResponseStatus: 200, + inputEntries: []entry{logEntries[0], logEntries[3], logEntries[4], logEntries[5]}, + expectedReqs: []receivedReq{ + { + tenantID: "tenant-default", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[0].Entry}}}}, + }, + { + tenantID: "tenant-1", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[3].Entry, logEntries[4].Entry}}}}, + }, + { + tenantID: "tenant-2", + pushReq: logproto.PushRequest{Streams: []logproto.Stream{{Labels: "{}", Entries: []logproto.Entry{logEntries[5].Entry}}}}, + }, + }, + expectedMetrics: ` + # HELP promtail_sent_entries_total Number of log entries sent to the ingester. + # TYPE promtail_sent_entries_total counter + promtail_sent_entries_total{host="__HOST__"} 4.0 + # HELP promtail_dropped_entries_total Number of log entries dropped because failed to be sent to the ingester after all retries. + # TYPE promtail_dropped_entries_total counter + promtail_dropped_entries_total{host="__HOST__"} 0 + `, + }, + } + + for testName, testData := range tests { + t.Run(testName, func(t *testing.T) { + // Reset metrics + sentEntries.Reset() + droppedEntries.Reset() + + // Create a buffer channel where we do enqueue received requests + receivedReqsChan := make(chan receivedReq, 10) + + // Start a local HTTP server + server := httptest.NewServer(createServerHandler(receivedReqsChan, testData.serverResponseStatus)) + require.NotNil(t, server) + defer server.Close() + + // Get the URL at which the local test server is listening to + serverURL := urlutil.URLValue{} + err := serverURL.Set(server.URL) + require.NoError(t, err) + + // Instance the client + cfg := Config{ + URL: serverURL, + BatchWait: testData.clientBatchWait, + BatchSize: testData.clientBatchSize, + Client: config.HTTPClientConfig{}, + BackoffConfig: backoff.BackoffConfig{MinBackoff: 1 * time.Millisecond, MaxBackoff: 2 * time.Millisecond, MaxRetries: testData.clientMaxRetries}, + ExternalLabels: labelutil.LabelSet{}, + Timeout: 1 * time.Second, + TenantID: testData.clientTenantID, + } + + c, err := NewWithLogger(cfg, log.NewNopLogger()) + require.NoError(t, err) + + // Send all the input log entries + for i, logEntry := range testData.inputEntries { + err = c.Handle(logEntry.labels, logEntry.Timestamp, logEntry.Line) + require.NoError(t, err) + + if testData.inputDelay > 0 && i < len(testData.inputEntries)-1 { + time.Sleep(testData.inputDelay) + } + } + + // Wait until the expected push requests are received (with a timeout) + deadline := time.Now().Add(1 * time.Second) + for len(receivedReqsChan) < len(testData.expectedReqs) && time.Now().Before(deadline) { + time.Sleep(5 * time.Millisecond) + } + + // Stop the client: it waits until the current batch is sent + c.Stop() + close(receivedReqsChan) + + // Get all push requests received on the server side + receivedReqs := make([]receivedReq, 0) + for req := range receivedReqsChan { + receivedReqs = append(receivedReqs, req) + } + + // Due to implementation details (maps iteration ordering is random) we just check + // that the expected requests are equal to the received requests, without checking + // the exact order which is not guaranteed in case of multi-tenant + require.ElementsMatch(t, testData.expectedReqs, receivedReqs) + + expectedMetrics := strings.Replace(testData.expectedMetrics, "__HOST__", serverURL.Host, -1) + err = testutil.GatherAndCompare(prometheus.DefaultGatherer, strings.NewReader(expectedMetrics), "promtail_sent_entries_total", "promtail_dropped_entries_total") + assert.NoError(t, err) + }) + } +} + +func createServerHandler(receivedReqsChan chan receivedReq, status int) http.HandlerFunc { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + // Parse the request + var pushReq logproto.PushRequest + if err := httputil.ParseProtoReader(req.Context(), req.Body, int(req.ContentLength), math.MaxInt32, &pushReq, httputil.RawSnappy); err != nil { + rw.WriteHeader(500) + return + } + + receivedReqsChan <- receivedReq{ + tenantID: req.Header.Get("X-Scope-OrgID"), + pushReq: pushReq, + } + + rw.WriteHeader(status) + }) +} + +type roundTripFunc func(r *http.Request) (*http.Response, error) + +func (s roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { + return s(r) +} + +func TestClient_EncodeJSON(t *testing.T) { + c, err := NewWithDefault("http://loki.com/loki/api/v1/push") + require.NoError(t, err) + c.cfg.EncodeJson = true + + c.client.Transport = roundTripFunc(func(r *http.Request) (*http.Response, error) { + require.Equal(t, r.Header.Get("Content-Type"), JSONContentType) + require.Equal(t, r.URL.Path, "/loki/api/v1/push") + b, err := ioutil.ReadAll(r.Body) + require.NoError(t, err) + require.Equal(t, `{"streams":[{"stream":{"foo":"bar"},"values":[["1","11"],["2","22"]]},{"stream":{"foo":"buzz"},"values":[["3","33"],["4","44"]]}]}`, string(b)) + return &http.Response{StatusCode: 200, Body: http.NoBody}, nil + }) + + c.sendBatch("", + newBatch( + entry{labels: model.LabelSet{"foo": "bar"}, Entry: logproto.Entry{Timestamp: time.Unix(0, 1), Line: "11"}}, + entry{labels: model.LabelSet{"foo": "bar"}, Entry: logproto.Entry{Timestamp: time.Unix(0, 2), Line: "22"}}, + entry{labels: model.LabelSet{"foo": "buzz"}, Entry: logproto.Entry{Timestamp: time.Unix(0, 3), Line: "33"}}, + entry{labels: model.LabelSet{"foo": "buzz"}, Entry: logproto.Entry{Timestamp: time.Unix(0, 4), Line: "44"}}, + ), + ) +} diff --git a/loki/config.go b/loki/config.go new file mode 100644 index 0000000..c67aecc --- /dev/null +++ b/loki/config.go @@ -0,0 +1,109 @@ +package loki + +import ( + "flag" + "time" + + "github.com/lixh00/loki-client-go/pkg/backoff" + "github.com/lixh00/loki-client-go/pkg/labelutil" + "github.com/lixh00/loki-client-go/pkg/urlutil" + "github.com/prometheus/common/config" +) + +// NOTE the helm chart for promtail and fluent-bit also have defaults for these values, please update to match if you make changes here. +const ( + BatchWait = 1 * time.Second + BatchSize int = 1024 * 1024 + MinBackoff = 500 * time.Millisecond + MaxBackoff = 5 * time.Minute + MaxRetries int = 10 + Timeout = 10 * time.Second +) + +// Config describes configuration for a HTTP pusher client. +type Config struct { + URL urlutil.URLValue + BatchWait time.Duration + BatchSize int + + Client config.HTTPClientConfig `yaml:",inline"` + + BackoffConfig backoff.BackoffConfig `yaml:"backoff_config"` + // The labels to add to any time series or alerts when communicating with loki + ExternalLabels labelutil.LabelSet `yaml:"external_labels,omitempty"` + Timeout time.Duration `yaml:"timeout"` + + // The tenant ID to use when pushing logs to Loki (empty string means + // single tenant mode) + TenantID string `yaml:"tenant_id"` + + // Use Loki JSON api as opposed to the snappy protobuf. + EncodeJson bool `yaml:"encode_json"` +} + +// NewDefaultConfig creates a default configuration for a given target Loki URL. +func NewDefaultConfig(url string) (Config, error) { + var cfg Config + var u urlutil.URLValue + f := &flag.FlagSet{} + cfg.RegisterFlags(f) + if err := f.Parse(nil); err != nil { + return cfg, err + } + if err := u.Set(url); err != nil { + return cfg, err + } + cfg.URL = u + return cfg, nil +} + +// RegisterFlags with prefix registers flags where every name is prefixed by +// prefix. If prefix is a non-empty string, prefix should end with a period. +func (c *Config) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { + f.Var(&c.URL, prefix+"client.url", "URL of log server") + f.DurationVar(&c.BatchWait, prefix+"client.batch-wait", BatchWait, "Maximum wait period before sending batch.") + f.IntVar(&c.BatchSize, prefix+"client.batch-size-bytes", BatchSize, "Maximum batch size to accrue before sending. ") + // Default backoff schedule: 0.5s, 1s, 2s, 4s, 8s, 16s, 32s, 64s, 128s, 256s(4.267m) For a total time of 511.5s(8.5m) before logs are lost + f.IntVar(&c.BackoffConfig.MaxRetries, prefix+"client.max-retries", MaxRetries, "Maximum number of retires when sending batches.") + f.DurationVar(&c.BackoffConfig.MinBackoff, prefix+"client.min-backoff", MinBackoff, "Initial backoff time between retries.") + f.DurationVar(&c.BackoffConfig.MaxBackoff, prefix+"client.max-backoff", MaxBackoff, "Maximum backoff time between retries.") + f.DurationVar(&c.Timeout, prefix+"client.timeout", Timeout, "Maximum time to wait for server to respond to a request") + f.Var(&c.ExternalLabels, prefix+"client.external-labels", "list of external labels to add to each log (e.g: --client.external-labels=lb1=v1,lb2=v2)") + + f.StringVar(&c.TenantID, prefix+"client.tenant-id", "", "Tenant ID to use when pushing logs to Loki.") + f.BoolVar(&c.EncodeJson, prefix+"client.encode-json", false, "Encode payload in JSON, default to snappy protobuf") +} + +// RegisterFlags registers flags. +func (c *Config) RegisterFlags(flags *flag.FlagSet) { + c.RegisterFlagsWithPrefix("", flags) +} + +// UnmarshalYAML implement Yaml Unmarshaler +func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { + type raw Config + var cfg raw + if c.URL.URL != nil { + // we used flags to set that value, which already has sane default. + cfg = raw(*c) + } else { + // force sane defaults. + cfg = raw{ + BackoffConfig: backoff.BackoffConfig{ + MaxBackoff: MaxBackoff, + MaxRetries: MaxRetries, + MinBackoff: MinBackoff, + }, + BatchSize: BatchSize, + BatchWait: BatchWait, + Timeout: Timeout, + } + } + + if err := unmarshal(&cfg); err != nil { + return err + } + + *c = Config(cfg) + return nil +} diff --git a/loki/config_test.go b/loki/config_test.go new file mode 100644 index 0000000..2db084d --- /dev/null +++ b/loki/config_test.go @@ -0,0 +1,94 @@ +package loki + +import ( + "net/url" + "reflect" + "testing" + "time" + + "github.com/lixh00/loki-client-go/pkg/backoff" + "github.com/lixh00/loki-client-go/pkg/urlutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "gopkg.in/yaml.v2" +) + +var clientConfig = Config{} + +var clientDefaultConfig = (` +url: http://localhost:3100/loki/api/v1/push +`) + +var clientCustomConfig = ` +url: http://localhost:3100/loki/api/v1/push +backoff_config: + max_retries: 20 + min_period: 5s + max_period: 1m +batchwait: 5s +batchsize: 204800 +timeout: 5s +` + +func Test_Config(t *testing.T) { + u, err := url.Parse("http://localhost:3100/loki/api/v1/push") + require.NoError(t, err) + tests := []struct { + configValues string + expectedConfig Config + }{ + { + clientDefaultConfig, + Config{ + URL: urlutil.URLValue{ + URL: u, + }, + BackoffConfig: backoff.BackoffConfig{ + MaxBackoff: MaxBackoff, + MaxRetries: MaxRetries, + MinBackoff: MinBackoff, + }, + BatchSize: BatchSize, + BatchWait: BatchWait, + Timeout: Timeout, + }, + }, + { + clientCustomConfig, + Config{ + URL: urlutil.URLValue{ + URL: u, + }, + BackoffConfig: backoff.BackoffConfig{ + MaxBackoff: 1 * time.Minute, + MaxRetries: 20, + MinBackoff: 5 * time.Second, + }, + BatchSize: 100 * 2048, + BatchWait: 5 * time.Second, + Timeout: 5 * time.Second, + }, + }, + } + for _, tc := range tests { + err := yaml.Unmarshal([]byte(tc.configValues), &clientConfig) + require.NoError(t, err) + + if !reflect.DeepEqual(tc.expectedConfig, clientConfig) { + t.Errorf("Configs does not match, expected: %v, received: %v", tc.expectedConfig, clientConfig) + } + } +} + +func TestDefaultConfig(t *testing.T) { + cfg, err := NewDefaultConfig("http://loki.com") + assert.Nil(t, err) + assert.Equal(t, cfg.BatchSize, BatchSize) + assert.Equal(t, cfg.BatchWait, BatchWait) + assert.Equal(t, cfg.Timeout, Timeout) + assert.Equal(t, cfg.BackoffConfig.MaxBackoff, MaxBackoff) + assert.Equal(t, cfg.BackoffConfig.MinBackoff, MinBackoff) + assert.Equal(t, cfg.BackoffConfig.MaxRetries, MaxRetries) + assert.Equal(t, cfg.URL.URL.String(), "http://loki.com") +} diff --git a/pkg/backoff/backoff.go b/pkg/backoff/backoff.go new file mode 100644 index 0000000..3c922c1 --- /dev/null +++ b/pkg/backoff/backoff.go @@ -0,0 +1,117 @@ +package backoff + +import ( + "context" + "flag" + "fmt" + "math/rand" + "time" +) + +// BackoffConfig configures a Backoff +type BackoffConfig struct { + MinBackoff time.Duration `yaml:"min_period"` // start backoff at this level + MaxBackoff time.Duration `yaml:"max_period"` // increase exponentially to this level + MaxRetries int `yaml:"max_retries"` // give up after this many; zero means infinite retries +} + +// RegisterFlags for BackoffConfig. +func (cfg *BackoffConfig) RegisterFlags(prefix string, f *flag.FlagSet) { + f.DurationVar(&cfg.MinBackoff, prefix+".backoff-min-period", 100*time.Millisecond, "Minimum delay when backing off.") + f.DurationVar(&cfg.MaxBackoff, prefix+".backoff-max-period", 10*time.Second, "Maximum delay when backing off.") + f.IntVar(&cfg.MaxRetries, prefix+".backoff-retries", 10, "Number of times to backoff and retry before failing.") +} + +// Backoff implements exponential backoff with randomized wait times +type Backoff struct { + cfg BackoffConfig + ctx context.Context + numRetries int + nextDelayMin time.Duration + nextDelayMax time.Duration +} + +// New creates a Backoff object. Pass a Context that can also terminate the operation. +func New(ctx context.Context, cfg BackoffConfig) *Backoff { + return &Backoff{ + cfg: cfg, + ctx: ctx, + nextDelayMin: cfg.MinBackoff, + nextDelayMax: doubleDuration(cfg.MinBackoff, cfg.MaxBackoff), + } +} + +// Reset the Backoff back to its initial condition +func (b *Backoff) Reset() { + b.numRetries = 0 + b.nextDelayMin = b.cfg.MinBackoff + b.nextDelayMax = doubleDuration(b.cfg.MinBackoff, b.cfg.MaxBackoff) +} + +// Ongoing returns true if caller should keep going +func (b *Backoff) Ongoing() bool { + // Stop if Context has errored or max retry count is exceeded + return b.ctx.Err() == nil && (b.cfg.MaxRetries == 0 || b.numRetries < b.cfg.MaxRetries) +} + +// Err returns the reason for terminating the backoff, or nil if it didn't terminate +func (b *Backoff) Err() error { + if b.ctx.Err() != nil { + return b.ctx.Err() + } + if b.cfg.MaxRetries != 0 && b.numRetries >= b.cfg.MaxRetries { + return fmt.Errorf("terminated after %d retries", b.numRetries) + } + return nil +} + +// NumRetries returns the number of retries so far +func (b *Backoff) NumRetries() int { + return b.numRetries +} + +// Wait sleeps for the backoff time then increases the retry count and backoff time +// Returns immediately if Context is terminated +func (b *Backoff) Wait() { + // Increase the number of retries and get the next delay + sleepTime := b.NextDelay() + + if b.Ongoing() { + select { + case <-b.ctx.Done(): + case <-time.After(sleepTime): + } + } +} + +func (b *Backoff) NextDelay() time.Duration { + b.numRetries++ + + // Handle the edge case the min and max have the same value + // (or due to some misconfig max is < min) + if b.nextDelayMin >= b.nextDelayMax { + return b.nextDelayMin + } + + // Add a jitter within the next exponential backoff range + sleepTime := b.nextDelayMin + time.Duration(rand.Int63n(int64(b.nextDelayMax-b.nextDelayMin))) + + // Apply the exponential backoff to calculate the next jitter + // range, unless we've already reached the max + if b.nextDelayMax < b.cfg.MaxBackoff { + b.nextDelayMin = doubleDuration(b.nextDelayMin, b.cfg.MaxBackoff) + b.nextDelayMax = doubleDuration(b.nextDelayMax, b.cfg.MaxBackoff) + } + + return sleepTime +} + +func doubleDuration(value time.Duration, max time.Duration) time.Duration { + value = value * 2 + + if value <= max { + return value + } + + return max +} diff --git a/pkg/helpers/config.go b/pkg/helpers/config.go new file mode 100644 index 0000000..7dce226 --- /dev/null +++ b/pkg/helpers/config.go @@ -0,0 +1,18 @@ +package helpers + +import ( + "io/ioutil" + + "github.com/pkg/errors" + yaml "gopkg.in/yaml.v2" +) + +// LoadConfig read YAML-formatted config from filename into cfg. +func LoadConfig(filename string, cfg interface{}) error { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return errors.Wrap(err, "Error reading config file") + } + + return yaml.UnmarshalStrict(buf, cfg) +} diff --git a/pkg/helpers/logerror.go b/pkg/helpers/logerror.go new file mode 100644 index 0000000..dd75ff5 --- /dev/null +++ b/pkg/helpers/logerror.go @@ -0,0 +1,13 @@ +package helpers + +import ( + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" +) + +// LogError logs any error returned by f; useful when deferring Close etc. +func LogError(logger log.Logger, message string, f func() error) { + if err := f(); err != nil { + level.Error(logger).Log("message", message, "error", err) + } +} diff --git a/pkg/helpers/math.go b/pkg/helpers/math.go new file mode 100644 index 0000000..2902683 --- /dev/null +++ b/pkg/helpers/math.go @@ -0,0 +1,9 @@ +package helpers + +// MinUint32 return the min of a and b. +func MinUint32(a, b uint32) uint32 { + if a < b { + return a + } + return b +} diff --git a/pkg/httputil/http.go b/pkg/httputil/http.go new file mode 100644 index 0000000..8916a1f --- /dev/null +++ b/pkg/httputil/http.go @@ -0,0 +1,164 @@ +package httputil + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "html/template" + "io" + "net/http" + "strings" + + "github.com/blang/semver" + "github.com/gogo/protobuf/proto" + "github.com/golang/snappy" + "github.com/opentracing/opentracing-go" + otlog "github.com/opentracing/opentracing-go/log" +) + +// WriteJSONResponse writes some JSON as a HTTP response. +func WriteJSONResponse(w http.ResponseWriter, v interface{}) { + data, err := json.Marshal(v) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if _, err = w.Write(data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") +} + +// RenderHTTPResponse either responds with json or a rendered html page using the passed in template +// by checking the Accepts header +func RenderHTTPResponse(w http.ResponseWriter, v interface{}, t *template.Template, r *http.Request) { + accept := r.Header.Get("Accept") + if strings.Contains(accept, "application/json") { + WriteJSONResponse(w, v) + return + } + + err := t.Execute(w, v) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +// CompressionType for encoding and decoding requests and responses. +type CompressionType int + +// Values for CompressionType +const ( + NoCompression CompressionType = iota + FramedSnappy + RawSnappy +) + +var rawSnappyFromVersion = semver.MustParse("0.1.0") + +// CompressionTypeFor a given version of the Prometheus remote storage protocol. +// See https://github.com/prometheus/prometheus/issues/2692. +func CompressionTypeFor(version string) CompressionType { + ver, err := semver.Make(version) + if err != nil { + return FramedSnappy + } + + if ver.GTE(rawSnappyFromVersion) { + return RawSnappy + } + return FramedSnappy +} + +// ParseProtoReader parses a compressed proto from an io.Reader. +func ParseProtoReader(ctx context.Context, reader io.Reader, expectedSize, maxSize int, req proto.Message, compression CompressionType) error { + var body []byte + var err error + sp := opentracing.SpanFromContext(ctx) + if sp != nil { + sp.LogFields(otlog.String("event", "util.ParseProtoRequest[start reading]")) + } + var buf bytes.Buffer + if expectedSize > 0 { + if expectedSize > maxSize { + return fmt.Errorf("message expected size larger than max (%d vs %d)", expectedSize, maxSize) + } + buf.Grow(expectedSize + bytes.MinRead) // extra space guarantees no reallocation + } + switch compression { + case NoCompression: + // Read from LimitReader with limit max+1. So if the underlying + // reader is over limit, the result will be bigger than max. + _, err = buf.ReadFrom(io.LimitReader(reader, int64(maxSize)+1)) + body = buf.Bytes() + case FramedSnappy: + _, err = buf.ReadFrom(io.LimitReader(snappy.NewReader(reader), int64(maxSize)+1)) + body = buf.Bytes() + case RawSnappy: + _, err = buf.ReadFrom(reader) + body = buf.Bytes() + if sp != nil { + sp.LogFields(otlog.String("event", "util.ParseProtoRequest[decompress]"), + otlog.Int("size", len(body))) + } + if err == nil && len(body) <= maxSize { + body, err = snappy.Decode(nil, body) + } + } + if err != nil { + return err + } + if len(body) > maxSize { + return fmt.Errorf("received message larger than max (%d vs %d)", len(body), maxSize) + } + + if sp != nil { + sp.LogFields(otlog.String("event", "util.ParseProtoRequest[unmarshal]"), + otlog.Int("size", len(body))) + } + + // We re-implement proto.Unmarshal here as it calls XXX_Unmarshal first, + // which we can't override without upsetting golint. + req.Reset() + if u, ok := req.(proto.Unmarshaler); ok { + err = u.Unmarshal(body) + } else { + err = proto.NewBuffer(body).Unmarshal(req) + } + if err != nil { + return err + } + + return nil +} + +// SerializeProtoResponse serializes a protobuf response into an HTTP response. +func SerializeProtoResponse(w http.ResponseWriter, resp proto.Message, compression CompressionType) error { + data, err := proto.Marshal(resp) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return fmt.Errorf("error marshaling proto response: %v", err) + } + + switch compression { + case NoCompression: + case FramedSnappy: + buf := bytes.Buffer{} + writer := snappy.NewBufferedWriter(&buf) + if _, err := writer.Write(data); err != nil { + return err + } + writer.Close() + data = buf.Bytes() + case RawSnappy: + data = snappy.Encode(nil, data) + } + + if _, err := w.Write(data); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return fmt.Errorf("error sending proto response: %v", err) + } + return nil +} diff --git a/pkg/labelutil/label.go b/pkg/labelutil/label.go new file mode 100644 index 0000000..6df0b04 --- /dev/null +++ b/pkg/labelutil/label.go @@ -0,0 +1,99 @@ +package labelutil + +import ( + "bytes" + "encoding/csv" + "fmt" + "strings" + + "github.com/prometheus/common/model" + "gopkg.in/yaml.v2" +) + +// LabelSet is a labelSet that can be used as a flag. +type LabelSet struct { + model.LabelSet `yaml:",inline"` +} + +// String implements flag.Value +// Format: a=1,b=2 +func (v LabelSet) String() string { + if v.LabelSet == nil { + return "" + } + records := make([]string, 0, len(v.LabelSet)>>1) + for k, v := range v.LabelSet { + records = append(records, string(k)+"="+string(v)) + } + + var buf bytes.Buffer + w := csv.NewWriter(&buf) + if err := w.Write(records); err != nil { + panic(err) + } + w.Flush() + return "[" + strings.TrimSpace(buf.String()) + "]" +} + +// Set implements flag.Value +func (v *LabelSet) Set(s string) error { + var ss []string + n := strings.Count(s, "=") + switch n { + case 0: + return fmt.Errorf("%s must be formatted as key=value", s) + case 1: + ss = append(ss, strings.Trim(s, `"`)) + default: + r := csv.NewReader(strings.NewReader(s)) + var err error + ss, err = r.Read() + if err != nil { + return err + } + } + + out := model.LabelSet{} + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("%s must be formatted as key=value", pair) + } + out[model.LabelName(kv[0])] = model.LabelValue(kv[1]) + } + + if err := out.Validate(); err != nil { + return err + } + v.LabelSet = out + return nil +} + +// UnmarshalYAML the Unmarshaler interface of the yaml pkg. +func (v *LabelSet) UnmarshalYAML(unmarshal func(interface{}) error) error { + lbSet := model.LabelSet{} + err := unmarshal(&lbSet) + if err != nil { + return err + } + v.LabelSet = lbSet + return nil +} + +// MarshalYAML implements yaml.Marshaller. +func (v LabelSet) MarshalYAML() (interface{}, error) { + out, err := yaml.Marshal(ModelLabelSetToMap(v.LabelSet)) + if err != nil { + return nil, err + } + return string(out), nil +} + +// ModelLabelSetToMap convert a model.LabelSet to a map[string]string +func ModelLabelSetToMap(m model.LabelSet) map[string]string { + result := map[string]string{} + for k, v := range m { + result[string(k)] = string(v) + } + return result +} diff --git a/pkg/logproto/extensions.go b/pkg/logproto/extensions.go new file mode 100644 index 0000000..3a68d26 --- /dev/null +++ b/pkg/logproto/extensions.go @@ -0,0 +1,23 @@ +package logproto + +import "github.com/prometheus/prometheus/pkg/labels" + +// Note, this is not very efficient and use should be minimized as it requires label construction on each comparison +type SeriesIdentifiers []SeriesIdentifier + +func (ids SeriesIdentifiers) Len() int { return len(ids) } +func (ids SeriesIdentifiers) Swap(i, j int) { ids[i], ids[j] = ids[j], ids[i] } +func (ids SeriesIdentifiers) Less(i, j int) bool { + a, b := labels.FromMap(ids[i].Labels), labels.FromMap(ids[j].Labels) + return labels.Compare(a, b) <= 0 +} + +type Streams []Stream + +func (xs Streams) Len() int { return len(xs) } +func (xs Streams) Swap(i, j int) { xs[i], xs[j] = xs[j], xs[i] } +func (xs Streams) Less(i, j int) bool { return xs[i].Labels <= xs[j].Labels } + +func (s Series) Len() int { return len(s.Samples) } +func (s Series) Swap(i, j int) { s.Samples[i], s.Samples[j] = s.Samples[j], s.Samples[i] } +func (s Series) Less(i, j int) bool { return s.Samples[i].Timestamp < s.Samples[j].Timestamp } diff --git a/pkg/logproto/logproto.pb.go b/pkg/logproto/logproto.pb.go new file mode 100644 index 0000000..b1acaa0 --- /dev/null +++ b/pkg/logproto/logproto.pb.go @@ -0,0 +1,8031 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pkg/logproto/logproto.proto + +package logproto + +import ( + bytes "bytes" + context "context" + encoding_binary "encoding/binary" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + _ "github.com/gogo/protobuf/types" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + grpc "google.golang.org/grpc" + io "io" + math "math" + reflect "reflect" + strconv "strconv" + strings "strings" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Direction int32 + +const ( + FORWARD Direction = 0 + BACKWARD Direction = 1 +) + +var Direction_name = map[int32]string{ + 0: "FORWARD", + 1: "BACKWARD", +} + +var Direction_value = map[string]int32{ + "FORWARD": 0, + "BACKWARD": 1, +} + +func (Direction) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{0} +} + +type PushRequest struct { + Streams []Stream `protobuf:"bytes,1,rep,name=streams,proto3,customtype=Stream" json:"streams"` +} + +func (m *PushRequest) Reset() { *m = PushRequest{} } +func (*PushRequest) ProtoMessage() {} +func (*PushRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{0} +} +func (m *PushRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PushRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PushRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PushRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PushRequest.Merge(m, src) +} +func (m *PushRequest) XXX_Size() int { + return m.Size() +} +func (m *PushRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PushRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PushRequest proto.InternalMessageInfo + +type PushResponse struct { +} + +func (m *PushResponse) Reset() { *m = PushResponse{} } +func (*PushResponse) ProtoMessage() {} +func (*PushResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{1} +} +func (m *PushResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PushResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PushResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PushResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PushResponse.Merge(m, src) +} +func (m *PushResponse) XXX_Size() int { + return m.Size() +} +func (m *PushResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PushResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PushResponse proto.InternalMessageInfo + +type QueryRequest struct { + Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` + Limit uint32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + Start time.Time `protobuf:"bytes,3,opt,name=start,proto3,stdtime" json:"start"` + End time.Time `protobuf:"bytes,4,opt,name=end,proto3,stdtime" json:"end"` + Direction Direction `protobuf:"varint,5,opt,name=direction,proto3,enum=logproto.Direction" json:"direction,omitempty"` + Shards []string `protobuf:"bytes,7,rep,name=shards,proto3" json:"shards,omitempty"` +} + +func (m *QueryRequest) Reset() { *m = QueryRequest{} } +func (*QueryRequest) ProtoMessage() {} +func (*QueryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{2} +} +func (m *QueryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRequest.Merge(m, src) +} +func (m *QueryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRequest proto.InternalMessageInfo + +func (m *QueryRequest) GetSelector() string { + if m != nil { + return m.Selector + } + return "" +} + +func (m *QueryRequest) GetLimit() uint32 { + if m != nil { + return m.Limit + } + return 0 +} + +func (m *QueryRequest) GetStart() time.Time { + if m != nil { + return m.Start + } + return time.Time{} +} + +func (m *QueryRequest) GetEnd() time.Time { + if m != nil { + return m.End + } + return time.Time{} +} + +func (m *QueryRequest) GetDirection() Direction { + if m != nil { + return m.Direction + } + return FORWARD +} + +func (m *QueryRequest) GetShards() []string { + if m != nil { + return m.Shards + } + return nil +} + +type SampleQueryRequest struct { + Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` + Start time.Time `protobuf:"bytes,2,opt,name=start,proto3,stdtime" json:"start"` + End time.Time `protobuf:"bytes,3,opt,name=end,proto3,stdtime" json:"end"` + Shards []string `protobuf:"bytes,4,rep,name=shards,proto3" json:"shards,omitempty"` +} + +func (m *SampleQueryRequest) Reset() { *m = SampleQueryRequest{} } +func (*SampleQueryRequest) ProtoMessage() {} +func (*SampleQueryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{3} +} +func (m *SampleQueryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SampleQueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SampleQueryRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SampleQueryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SampleQueryRequest.Merge(m, src) +} +func (m *SampleQueryRequest) XXX_Size() int { + return m.Size() +} +func (m *SampleQueryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SampleQueryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SampleQueryRequest proto.InternalMessageInfo + +func (m *SampleQueryRequest) GetSelector() string { + if m != nil { + return m.Selector + } + return "" +} + +func (m *SampleQueryRequest) GetStart() time.Time { + if m != nil { + return m.Start + } + return time.Time{} +} + +func (m *SampleQueryRequest) GetEnd() time.Time { + if m != nil { + return m.End + } + return time.Time{} +} + +func (m *SampleQueryRequest) GetShards() []string { + if m != nil { + return m.Shards + } + return nil +} + +type SampleQueryResponse struct { + Series []Series `protobuf:"bytes,1,rep,name=series,proto3,customtype=Series" json:"series,omitempty"` +} + +func (m *SampleQueryResponse) Reset() { *m = SampleQueryResponse{} } +func (*SampleQueryResponse) ProtoMessage() {} +func (*SampleQueryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{4} +} +func (m *SampleQueryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SampleQueryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SampleQueryResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SampleQueryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SampleQueryResponse.Merge(m, src) +} +func (m *SampleQueryResponse) XXX_Size() int { + return m.Size() +} +func (m *SampleQueryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SampleQueryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SampleQueryResponse proto.InternalMessageInfo + +type QueryResponse struct { + Streams []Stream `protobuf:"bytes,1,rep,name=streams,proto3,customtype=Stream" json:"streams,omitempty"` +} + +func (m *QueryResponse) Reset() { *m = QueryResponse{} } +func (*QueryResponse) ProtoMessage() {} +func (*QueryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{5} +} +func (m *QueryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryResponse.Merge(m, src) +} +func (m *QueryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryResponse proto.InternalMessageInfo + +type LabelRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Values bool `protobuf:"varint,2,opt,name=values,proto3" json:"values,omitempty"` + Start *time.Time `protobuf:"bytes,3,opt,name=start,proto3,stdtime" json:"start,omitempty"` + End *time.Time `protobuf:"bytes,4,opt,name=end,proto3,stdtime" json:"end,omitempty"` +} + +func (m *LabelRequest) Reset() { *m = LabelRequest{} } +func (*LabelRequest) ProtoMessage() {} +func (*LabelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{6} +} +func (m *LabelRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LabelRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LabelRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LabelRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LabelRequest.Merge(m, src) +} +func (m *LabelRequest) XXX_Size() int { + return m.Size() +} +func (m *LabelRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LabelRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LabelRequest proto.InternalMessageInfo + +func (m *LabelRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *LabelRequest) GetValues() bool { + if m != nil { + return m.Values + } + return false +} + +func (m *LabelRequest) GetStart() *time.Time { + if m != nil { + return m.Start + } + return nil +} + +func (m *LabelRequest) GetEnd() *time.Time { + if m != nil { + return m.End + } + return nil +} + +type LabelResponse struct { + Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` +} + +func (m *LabelResponse) Reset() { *m = LabelResponse{} } +func (*LabelResponse) ProtoMessage() {} +func (*LabelResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{7} +} +func (m *LabelResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LabelResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LabelResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LabelResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LabelResponse.Merge(m, src) +} +func (m *LabelResponse) XXX_Size() int { + return m.Size() +} +func (m *LabelResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LabelResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LabelResponse proto.InternalMessageInfo + +func (m *LabelResponse) GetValues() []string { + if m != nil { + return m.Values + } + return nil +} + +type StreamAdapter struct { + Labels string `protobuf:"bytes,1,opt,name=labels,proto3" json:"labels"` + Entries []EntryAdapter `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries"` +} + +func (m *StreamAdapter) Reset() { *m = StreamAdapter{} } +func (*StreamAdapter) ProtoMessage() {} +func (*StreamAdapter) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{8} +} +func (m *StreamAdapter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StreamAdapter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StreamAdapter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StreamAdapter) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamAdapter.Merge(m, src) +} +func (m *StreamAdapter) XXX_Size() int { + return m.Size() +} +func (m *StreamAdapter) XXX_DiscardUnknown() { + xxx_messageInfo_StreamAdapter.DiscardUnknown(m) +} + +var xxx_messageInfo_StreamAdapter proto.InternalMessageInfo + +func (m *StreamAdapter) GetLabels() string { + if m != nil { + return m.Labels + } + return "" +} + +func (m *StreamAdapter) GetEntries() []EntryAdapter { + if m != nil { + return m.Entries + } + return nil +} + +type EntryAdapter struct { + Timestamp time.Time `protobuf:"bytes,1,opt,name=timestamp,proto3,stdtime" json:"ts"` + Line string `protobuf:"bytes,2,opt,name=line,proto3" json:"line"` +} + +func (m *EntryAdapter) Reset() { *m = EntryAdapter{} } +func (*EntryAdapter) ProtoMessage() {} +func (*EntryAdapter) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{9} +} +func (m *EntryAdapter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EntryAdapter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EntryAdapter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EntryAdapter) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntryAdapter.Merge(m, src) +} +func (m *EntryAdapter) XXX_Size() int { + return m.Size() +} +func (m *EntryAdapter) XXX_DiscardUnknown() { + xxx_messageInfo_EntryAdapter.DiscardUnknown(m) +} + +var xxx_messageInfo_EntryAdapter proto.InternalMessageInfo + +func (m *EntryAdapter) GetTimestamp() time.Time { + if m != nil { + return m.Timestamp + } + return time.Time{} +} + +func (m *EntryAdapter) GetLine() string { + if m != nil { + return m.Line + } + return "" +} + +type Sample struct { + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"ts"` + Value float64 `protobuf:"fixed64,2,opt,name=value,proto3" json:"value"` + Hash uint64 `protobuf:"varint,3,opt,name=hash,proto3" json:"hash"` +} + +func (m *Sample) Reset() { *m = Sample{} } +func (*Sample) ProtoMessage() {} +func (*Sample) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{10} +} +func (m *Sample) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Sample) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Sample.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Sample) XXX_Merge(src proto.Message) { + xxx_messageInfo_Sample.Merge(m, src) +} +func (m *Sample) XXX_Size() int { + return m.Size() +} +func (m *Sample) XXX_DiscardUnknown() { + xxx_messageInfo_Sample.DiscardUnknown(m) +} + +var xxx_messageInfo_Sample proto.InternalMessageInfo + +func (m *Sample) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *Sample) GetValue() float64 { + if m != nil { + return m.Value + } + return 0 +} + +func (m *Sample) GetHash() uint64 { + if m != nil { + return m.Hash + } + return 0 +} + +type Series struct { + Labels string `protobuf:"bytes,1,opt,name=labels,proto3" json:"labels"` + Samples []Sample `protobuf:"bytes,2,rep,name=samples,proto3" json:"samples"` +} + +func (m *Series) Reset() { *m = Series{} } +func (*Series) ProtoMessage() {} +func (*Series) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{11} +} +func (m *Series) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Series) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Series.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Series) XXX_Merge(src proto.Message) { + xxx_messageInfo_Series.Merge(m, src) +} +func (m *Series) XXX_Size() int { + return m.Size() +} +func (m *Series) XXX_DiscardUnknown() { + xxx_messageInfo_Series.DiscardUnknown(m) +} + +var xxx_messageInfo_Series proto.InternalMessageInfo + +func (m *Series) GetLabels() string { + if m != nil { + return m.Labels + } + return "" +} + +func (m *Series) GetSamples() []Sample { + if m != nil { + return m.Samples + } + return nil +} + +type TailRequest struct { + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + DelayFor uint32 `protobuf:"varint,3,opt,name=delayFor,proto3" json:"delayFor,omitempty"` + Limit uint32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + Start time.Time `protobuf:"bytes,5,opt,name=start,proto3,stdtime" json:"start"` +} + +func (m *TailRequest) Reset() { *m = TailRequest{} } +func (*TailRequest) ProtoMessage() {} +func (*TailRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{12} +} +func (m *TailRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TailRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TailRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TailRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TailRequest.Merge(m, src) +} +func (m *TailRequest) XXX_Size() int { + return m.Size() +} +func (m *TailRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TailRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_TailRequest proto.InternalMessageInfo + +func (m *TailRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (m *TailRequest) GetDelayFor() uint32 { + if m != nil { + return m.DelayFor + } + return 0 +} + +func (m *TailRequest) GetLimit() uint32 { + if m != nil { + return m.Limit + } + return 0 +} + +func (m *TailRequest) GetStart() time.Time { + if m != nil { + return m.Start + } + return time.Time{} +} + +type TailResponse struct { + Stream *Stream `protobuf:"bytes,1,opt,name=stream,proto3,customtype=Stream" json:"stream,omitempty"` + DroppedStreams []*DroppedStream `protobuf:"bytes,2,rep,name=droppedStreams,proto3" json:"droppedStreams,omitempty"` +} + +func (m *TailResponse) Reset() { *m = TailResponse{} } +func (*TailResponse) ProtoMessage() {} +func (*TailResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{13} +} +func (m *TailResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TailResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TailResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TailResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TailResponse.Merge(m, src) +} +func (m *TailResponse) XXX_Size() int { + return m.Size() +} +func (m *TailResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TailResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TailResponse proto.InternalMessageInfo + +func (m *TailResponse) GetDroppedStreams() []*DroppedStream { + if m != nil { + return m.DroppedStreams + } + return nil +} + +type SeriesRequest struct { + Start time.Time `protobuf:"bytes,1,opt,name=start,proto3,stdtime" json:"start"` + End time.Time `protobuf:"bytes,2,opt,name=end,proto3,stdtime" json:"end"` + Groups []string `protobuf:"bytes,3,rep,name=groups,proto3" json:"groups,omitempty"` +} + +func (m *SeriesRequest) Reset() { *m = SeriesRequest{} } +func (*SeriesRequest) ProtoMessage() {} +func (*SeriesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{14} +} +func (m *SeriesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SeriesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SeriesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SeriesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SeriesRequest.Merge(m, src) +} +func (m *SeriesRequest) XXX_Size() int { + return m.Size() +} +func (m *SeriesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SeriesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SeriesRequest proto.InternalMessageInfo + +func (m *SeriesRequest) GetStart() time.Time { + if m != nil { + return m.Start + } + return time.Time{} +} + +func (m *SeriesRequest) GetEnd() time.Time { + if m != nil { + return m.End + } + return time.Time{} +} + +func (m *SeriesRequest) GetGroups() []string { + if m != nil { + return m.Groups + } + return nil +} + +type SeriesResponse struct { + Series []SeriesIdentifier `protobuf:"bytes,1,rep,name=series,proto3" json:"series"` +} + +func (m *SeriesResponse) Reset() { *m = SeriesResponse{} } +func (*SeriesResponse) ProtoMessage() {} +func (*SeriesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{15} +} +func (m *SeriesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SeriesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SeriesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SeriesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SeriesResponse.Merge(m, src) +} +func (m *SeriesResponse) XXX_Size() int { + return m.Size() +} +func (m *SeriesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SeriesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SeriesResponse proto.InternalMessageInfo + +func (m *SeriesResponse) GetSeries() []SeriesIdentifier { + if m != nil { + return m.Series + } + return nil +} + +type SeriesIdentifier struct { + Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *SeriesIdentifier) Reset() { *m = SeriesIdentifier{} } +func (*SeriesIdentifier) ProtoMessage() {} +func (*SeriesIdentifier) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{16} +} +func (m *SeriesIdentifier) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SeriesIdentifier) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SeriesIdentifier.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SeriesIdentifier) XXX_Merge(src proto.Message) { + xxx_messageInfo_SeriesIdentifier.Merge(m, src) +} +func (m *SeriesIdentifier) XXX_Size() int { + return m.Size() +} +func (m *SeriesIdentifier) XXX_DiscardUnknown() { + xxx_messageInfo_SeriesIdentifier.DiscardUnknown(m) +} + +var xxx_messageInfo_SeriesIdentifier proto.InternalMessageInfo + +func (m *SeriesIdentifier) GetLabels() map[string]string { + if m != nil { + return m.Labels + } + return nil +} + +type DroppedStream struct { + From time.Time `protobuf:"bytes,1,opt,name=from,proto3,stdtime" json:"from"` + To time.Time `protobuf:"bytes,2,opt,name=to,proto3,stdtime" json:"to"` + Labels string `protobuf:"bytes,3,opt,name=labels,proto3" json:"labels,omitempty"` +} + +func (m *DroppedStream) Reset() { *m = DroppedStream{} } +func (*DroppedStream) ProtoMessage() {} +func (*DroppedStream) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{17} +} +func (m *DroppedStream) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DroppedStream) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DroppedStream.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DroppedStream) XXX_Merge(src proto.Message) { + xxx_messageInfo_DroppedStream.Merge(m, src) +} +func (m *DroppedStream) XXX_Size() int { + return m.Size() +} +func (m *DroppedStream) XXX_DiscardUnknown() { + xxx_messageInfo_DroppedStream.DiscardUnknown(m) +} + +var xxx_messageInfo_DroppedStream proto.InternalMessageInfo + +func (m *DroppedStream) GetFrom() time.Time { + if m != nil { + return m.From + } + return time.Time{} +} + +func (m *DroppedStream) GetTo() time.Time { + if m != nil { + return m.To + } + return time.Time{} +} + +func (m *DroppedStream) GetLabels() string { + if m != nil { + return m.Labels + } + return "" +} + +type TimeSeriesChunk struct { + FromIngesterId string `protobuf:"bytes,1,opt,name=from_ingester_id,json=fromIngesterId,proto3" json:"from_ingester_id,omitempty"` + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Labels []*LabelPair `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty"` + Chunks []*Chunk `protobuf:"bytes,4,rep,name=chunks,proto3" json:"chunks,omitempty"` +} + +func (m *TimeSeriesChunk) Reset() { *m = TimeSeriesChunk{} } +func (*TimeSeriesChunk) ProtoMessage() {} +func (*TimeSeriesChunk) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{18} +} +func (m *TimeSeriesChunk) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TimeSeriesChunk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TimeSeriesChunk.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TimeSeriesChunk) XXX_Merge(src proto.Message) { + xxx_messageInfo_TimeSeriesChunk.Merge(m, src) +} +func (m *TimeSeriesChunk) XXX_Size() int { + return m.Size() +} +func (m *TimeSeriesChunk) XXX_DiscardUnknown() { + xxx_messageInfo_TimeSeriesChunk.DiscardUnknown(m) +} + +var xxx_messageInfo_TimeSeriesChunk proto.InternalMessageInfo + +func (m *TimeSeriesChunk) GetFromIngesterId() string { + if m != nil { + return m.FromIngesterId + } + return "" +} + +func (m *TimeSeriesChunk) GetUserId() string { + if m != nil { + return m.UserId + } + return "" +} + +func (m *TimeSeriesChunk) GetLabels() []*LabelPair { + if m != nil { + return m.Labels + } + return nil +} + +func (m *TimeSeriesChunk) GetChunks() []*Chunk { + if m != nil { + return m.Chunks + } + return nil +} + +type LabelPair struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *LabelPair) Reset() { *m = LabelPair{} } +func (*LabelPair) ProtoMessage() {} +func (*LabelPair) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{19} +} +func (m *LabelPair) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LabelPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LabelPair.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LabelPair) XXX_Merge(src proto.Message) { + xxx_messageInfo_LabelPair.Merge(m, src) +} +func (m *LabelPair) XXX_Size() int { + return m.Size() +} +func (m *LabelPair) XXX_DiscardUnknown() { + xxx_messageInfo_LabelPair.DiscardUnknown(m) +} + +var xxx_messageInfo_LabelPair proto.InternalMessageInfo + +func (m *LabelPair) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *LabelPair) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +type Chunk struct { + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *Chunk) Reset() { *m = Chunk{} } +func (*Chunk) ProtoMessage() {} +func (*Chunk) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{20} +} +func (m *Chunk) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Chunk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Chunk.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Chunk) XXX_Merge(src proto.Message) { + xxx_messageInfo_Chunk.Merge(m, src) +} +func (m *Chunk) XXX_Size() int { + return m.Size() +} +func (m *Chunk) XXX_DiscardUnknown() { + xxx_messageInfo_Chunk.DiscardUnknown(m) +} + +var xxx_messageInfo_Chunk proto.InternalMessageInfo + +func (m *Chunk) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +type TransferChunksResponse struct { +} + +func (m *TransferChunksResponse) Reset() { *m = TransferChunksResponse{} } +func (*TransferChunksResponse) ProtoMessage() {} +func (*TransferChunksResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{21} +} +func (m *TransferChunksResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TransferChunksResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TransferChunksResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TransferChunksResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TransferChunksResponse.Merge(m, src) +} +func (m *TransferChunksResponse) XXX_Size() int { + return m.Size() +} +func (m *TransferChunksResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TransferChunksResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TransferChunksResponse proto.InternalMessageInfo + +type TailersCountRequest struct { +} + +func (m *TailersCountRequest) Reset() { *m = TailersCountRequest{} } +func (*TailersCountRequest) ProtoMessage() {} +func (*TailersCountRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{22} +} +func (m *TailersCountRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TailersCountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TailersCountRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TailersCountRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TailersCountRequest.Merge(m, src) +} +func (m *TailersCountRequest) XXX_Size() int { + return m.Size() +} +func (m *TailersCountRequest) XXX_DiscardUnknown() { + xxx_messageInfo_TailersCountRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_TailersCountRequest proto.InternalMessageInfo + +type TailersCountResponse struct { + Count uint32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` +} + +func (m *TailersCountResponse) Reset() { *m = TailersCountResponse{} } +func (*TailersCountResponse) ProtoMessage() {} +func (*TailersCountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{23} +} +func (m *TailersCountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TailersCountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TailersCountResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TailersCountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TailersCountResponse.Merge(m, src) +} +func (m *TailersCountResponse) XXX_Size() int { + return m.Size() +} +func (m *TailersCountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TailersCountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TailersCountResponse proto.InternalMessageInfo + +func (m *TailersCountResponse) GetCount() uint32 { + if m != nil { + return m.Count + } + return 0 +} + +type GetChunkIDsRequest struct { + Matchers string `protobuf:"bytes,1,opt,name=matchers,proto3" json:"matchers,omitempty"` + Start time.Time `protobuf:"bytes,2,opt,name=start,proto3,stdtime" json:"start"` + End time.Time `protobuf:"bytes,3,opt,name=end,proto3,stdtime" json:"end"` +} + +func (m *GetChunkIDsRequest) Reset() { *m = GetChunkIDsRequest{} } +func (*GetChunkIDsRequest) ProtoMessage() {} +func (*GetChunkIDsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{24} +} +func (m *GetChunkIDsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetChunkIDsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetChunkIDsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetChunkIDsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetChunkIDsRequest.Merge(m, src) +} +func (m *GetChunkIDsRequest) XXX_Size() int { + return m.Size() +} +func (m *GetChunkIDsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetChunkIDsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetChunkIDsRequest proto.InternalMessageInfo + +func (m *GetChunkIDsRequest) GetMatchers() string { + if m != nil { + return m.Matchers + } + return "" +} + +func (m *GetChunkIDsRequest) GetStart() time.Time { + if m != nil { + return m.Start + } + return time.Time{} +} + +func (m *GetChunkIDsRequest) GetEnd() time.Time { + if m != nil { + return m.End + } + return time.Time{} +} + +type GetChunkIDsResponse struct { + ChunkIDs []string `protobuf:"bytes,1,rep,name=chunkIDs,proto3" json:"chunkIDs,omitempty"` +} + +func (m *GetChunkIDsResponse) Reset() { *m = GetChunkIDsResponse{} } +func (*GetChunkIDsResponse) ProtoMessage() {} +func (*GetChunkIDsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c28a5f14f1f4c79a, []int{25} +} +func (m *GetChunkIDsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetChunkIDsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetChunkIDsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetChunkIDsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetChunkIDsResponse.Merge(m, src) +} +func (m *GetChunkIDsResponse) XXX_Size() int { + return m.Size() +} +func (m *GetChunkIDsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetChunkIDsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetChunkIDsResponse proto.InternalMessageInfo + +func (m *GetChunkIDsResponse) GetChunkIDs() []string { + if m != nil { + return m.ChunkIDs + } + return nil +} + +func init() { + proto.RegisterEnum("logproto.Direction", Direction_name, Direction_value) + proto.RegisterType((*PushRequest)(nil), "logproto.PushRequest") + proto.RegisterType((*PushResponse)(nil), "logproto.PushResponse") + proto.RegisterType((*QueryRequest)(nil), "logproto.QueryRequest") + proto.RegisterType((*SampleQueryRequest)(nil), "logproto.SampleQueryRequest") + proto.RegisterType((*SampleQueryResponse)(nil), "logproto.SampleQueryResponse") + proto.RegisterType((*QueryResponse)(nil), "logproto.QueryResponse") + proto.RegisterType((*LabelRequest)(nil), "logproto.LabelRequest") + proto.RegisterType((*LabelResponse)(nil), "logproto.LabelResponse") + proto.RegisterType((*StreamAdapter)(nil), "logproto.StreamAdapter") + proto.RegisterType((*EntryAdapter)(nil), "logproto.EntryAdapter") + proto.RegisterType((*Sample)(nil), "logproto.Sample") + proto.RegisterType((*Series)(nil), "logproto.Series") + proto.RegisterType((*TailRequest)(nil), "logproto.TailRequest") + proto.RegisterType((*TailResponse)(nil), "logproto.TailResponse") + proto.RegisterType((*SeriesRequest)(nil), "logproto.SeriesRequest") + proto.RegisterType((*SeriesResponse)(nil), "logproto.SeriesResponse") + proto.RegisterType((*SeriesIdentifier)(nil), "logproto.SeriesIdentifier") + proto.RegisterMapType((map[string]string)(nil), "logproto.SeriesIdentifier.LabelsEntry") + proto.RegisterType((*DroppedStream)(nil), "logproto.DroppedStream") + proto.RegisterType((*TimeSeriesChunk)(nil), "logproto.TimeSeriesChunk") + proto.RegisterType((*LabelPair)(nil), "logproto.LabelPair") + proto.RegisterType((*Chunk)(nil), "logproto.Chunk") + proto.RegisterType((*TransferChunksResponse)(nil), "logproto.TransferChunksResponse") + proto.RegisterType((*TailersCountRequest)(nil), "logproto.TailersCountRequest") + proto.RegisterType((*TailersCountResponse)(nil), "logproto.TailersCountResponse") + proto.RegisterType((*GetChunkIDsRequest)(nil), "logproto.GetChunkIDsRequest") + proto.RegisterType((*GetChunkIDsResponse)(nil), "logproto.GetChunkIDsResponse") +} + +func init() { proto.RegisterFile("pkg/logproto/logproto.proto", fileDescriptor_c28a5f14f1f4c79a) } + +var fileDescriptor_c28a5f14f1f4c79a = []byte{ + // 1366 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0x4b, 0x8f, 0x13, 0xc7, + 0x13, 0x77, 0xfb, 0x31, 0xb6, 0xcb, 0x0f, 0xac, 0xde, 0x65, 0xd7, 0x7f, 0x03, 0x63, 0xab, 0x85, + 0xc0, 0xfa, 0x87, 0x78, 0x83, 0xf3, 0xe2, 0x91, 0x87, 0xd6, 0x6c, 0x08, 0x4b, 0x50, 0x80, 0x01, + 0x09, 0x09, 0x29, 0x42, 0xb3, 0x76, 0xaf, 0x3d, 0x5a, 0x7b, 0xc6, 0xcc, 0xb4, 0x91, 0xf6, 0x96, + 0x0f, 0x90, 0x48, 0xdc, 0x72, 0xe0, 0x9a, 0x43, 0x94, 0x43, 0x3e, 0x07, 0x47, 0x94, 0x13, 0xca, + 0xc1, 0x09, 0xe6, 0x12, 0xad, 0x72, 0xe0, 0x23, 0x44, 0xfd, 0x98, 0x99, 0xb6, 0xd9, 0x4d, 0x30, + 0x97, 0x5c, 0x3c, 0x5d, 0xd5, 0xd5, 0xd5, 0x55, 0xbf, 0xfe, 0x55, 0x75, 0x1b, 0x4e, 0x8c, 0xf7, + 0xfa, 0x1b, 0x43, 0xaf, 0x3f, 0xf6, 0x3d, 0xe6, 0x45, 0x83, 0x96, 0xf8, 0xc5, 0xb9, 0x50, 0xae, + 0xd5, 0xfb, 0x9e, 0xd7, 0x1f, 0xd2, 0x0d, 0x21, 0xed, 0x4c, 0x76, 0x37, 0x98, 0x33, 0xa2, 0x01, + 0xb3, 0x47, 0x63, 0x69, 0x5a, 0x7b, 0xb7, 0xef, 0xb0, 0xc1, 0x64, 0xa7, 0xd5, 0xf5, 0x46, 0x1b, + 0x7d, 0xaf, 0xef, 0xc5, 0x96, 0x5c, 0x92, 0xde, 0xf9, 0x48, 0x9a, 0x93, 0x7b, 0x50, 0xb8, 0x35, + 0x09, 0x06, 0x16, 0x7d, 0x38, 0xa1, 0x01, 0xc3, 0xd7, 0x20, 0x1b, 0x30, 0x9f, 0xda, 0xa3, 0xa0, + 0x8a, 0x1a, 0xa9, 0x66, 0xa1, 0xbd, 0xde, 0x8a, 0x42, 0xb9, 0x23, 0x26, 0x36, 0x7b, 0xf6, 0x98, + 0x51, 0xbf, 0x73, 0xfc, 0xb7, 0x69, 0xdd, 0x90, 0xaa, 0x83, 0x69, 0x3d, 0x5c, 0x65, 0x85, 0x03, + 0x52, 0x86, 0xa2, 0x74, 0x1c, 0x8c, 0x3d, 0x37, 0xa0, 0xe4, 0x49, 0x12, 0x8a, 0xb7, 0x27, 0xd4, + 0xdf, 0x0f, 0xb7, 0xaa, 0x41, 0x2e, 0xa0, 0x43, 0xda, 0x65, 0x9e, 0x5f, 0x45, 0x0d, 0xd4, 0xcc, + 0x5b, 0x91, 0x8c, 0x57, 0x21, 0x33, 0x74, 0x46, 0x0e, 0xab, 0x26, 0x1b, 0xa8, 0x59, 0xb2, 0xa4, + 0x80, 0x2f, 0x41, 0x26, 0x60, 0xb6, 0xcf, 0xaa, 0xa9, 0x06, 0x6a, 0x16, 0xda, 0xb5, 0x96, 0xc4, + 0xa2, 0x15, 0x66, 0xd8, 0xba, 0x1b, 0x62, 0xd1, 0xc9, 0x3d, 0x9d, 0xd6, 0x13, 0x8f, 0x7f, 0xaf, + 0x23, 0x4b, 0x2e, 0xc1, 0x1f, 0x41, 0x8a, 0xba, 0xbd, 0x6a, 0x7a, 0x89, 0x95, 0x7c, 0x01, 0x3e, + 0x0f, 0xf9, 0x9e, 0xe3, 0xd3, 0x2e, 0x73, 0x3c, 0xb7, 0x9a, 0x69, 0xa0, 0x66, 0xb9, 0xbd, 0x12, + 0x43, 0xb2, 0x15, 0x4e, 0x59, 0xb1, 0x15, 0x3e, 0x07, 0x46, 0x30, 0xb0, 0xfd, 0x5e, 0x50, 0xcd, + 0x36, 0x52, 0xcd, 0x7c, 0x67, 0xf5, 0x60, 0x5a, 0xaf, 0x48, 0xcd, 0x39, 0x6f, 0xe4, 0x30, 0x3a, + 0x1a, 0xb3, 0x7d, 0x4b, 0xd9, 0x5c, 0x4f, 0xe7, 0x8c, 0x4a, 0x96, 0xfc, 0x8a, 0x00, 0xdf, 0xb1, + 0x47, 0xe3, 0x21, 0x7d, 0x63, 0x8c, 0x22, 0x34, 0x92, 0x6f, 0x8d, 0x46, 0x6a, 0x59, 0x34, 0xe2, + 0xd4, 0xd2, 0xff, 0x9e, 0x1a, 0xb9, 0x09, 0x2b, 0x73, 0x39, 0x49, 0x26, 0xe0, 0x0b, 0x60, 0x04, + 0xd4, 0x77, 0x68, 0x48, 0xb1, 0x8a, 0x46, 0x31, 0xa1, 0xef, 0x94, 0x9f, 0x4e, 0xeb, 0x48, 0xf0, + 0x4b, 0xc8, 0x96, 0xb2, 0x27, 0x16, 0x94, 0xe6, 0x5d, 0x6d, 0xbe, 0x31, 0x5d, 0x63, 0x97, 0x42, + 0x1d, 0xf3, 0xf4, 0x17, 0x04, 0xc5, 0x1b, 0xf6, 0x0e, 0x1d, 0x86, 0x98, 0x63, 0x48, 0xbb, 0xf6, + 0x88, 0x2a, 0xbc, 0xc5, 0x18, 0xaf, 0x81, 0xf1, 0xc8, 0x1e, 0x4e, 0x68, 0x20, 0xc0, 0xce, 0x59, + 0x4a, 0x5a, 0x96, 0x91, 0xe8, 0xad, 0x19, 0x89, 0xa2, 0x33, 0x20, 0x67, 0xa1, 0xa4, 0xe2, 0x55, + 0x20, 0xc4, 0xc1, 0x71, 0x0c, 0xf2, 0x61, 0x70, 0xe4, 0x11, 0x94, 0xe6, 0x30, 0xc0, 0x04, 0x8c, + 0x21, 0x5f, 0x19, 0xc8, 0xdc, 0x3a, 0x70, 0x30, 0xad, 0x2b, 0x8d, 0xa5, 0xbe, 0x1c, 0x51, 0xea, + 0x32, 0x71, 0x3a, 0x49, 0x81, 0xe8, 0x5a, 0x8c, 0xe8, 0x17, 0x2e, 0xf3, 0xf7, 0x43, 0x40, 0x8f, + 0x71, 0x66, 0xf0, 0xca, 0x57, 0xe6, 0x56, 0x38, 0x20, 0x8f, 0xa0, 0xa8, 0x5b, 0xe2, 0x6b, 0x90, + 0x8f, 0x9a, 0x94, 0xd8, 0xf9, 0x9f, 0xd3, 0x2d, 0x2b, 0xc7, 0x49, 0x16, 0x88, 0xa4, 0xe3, 0xc5, + 0xf8, 0x24, 0xa4, 0x87, 0x8e, 0x4b, 0xc5, 0x21, 0xe4, 0x3b, 0xb9, 0x83, 0x69, 0x5d, 0xc8, 0x96, + 0xf8, 0x25, 0x23, 0x30, 0x24, 0xdd, 0xf0, 0xe9, 0xc5, 0x1d, 0x53, 0x1d, 0x43, 0x7a, 0xd4, 0xbd, + 0xd5, 0x21, 0x23, 0x90, 0x12, 0xee, 0x50, 0x27, 0x7f, 0x30, 0xad, 0x4b, 0x85, 0x25, 0x3f, 0x7c, + 0xbb, 0x81, 0x1d, 0x0c, 0xc4, 0xe1, 0xa6, 0xe5, 0x76, 0x5c, 0xb6, 0xc4, 0x2f, 0x71, 0x40, 0xd1, + 0xf3, 0x8d, 0x70, 0xbd, 0x0c, 0xd9, 0x40, 0x04, 0x17, 0xe2, 0xaa, 0xb3, 0x5e, 0x4c, 0xc4, 0x88, + 0x2a, 0x43, 0x2b, 0x1c, 0x90, 0x1f, 0x10, 0x14, 0xee, 0xda, 0x4e, 0x44, 0xd1, 0x55, 0xc8, 0x3c, + 0xe4, 0x75, 0xa0, 0x38, 0x2a, 0x05, 0xde, 0x2c, 0x7a, 0x74, 0x68, 0xef, 0x5f, 0xf5, 0x7c, 0x11, + 0x72, 0xc9, 0x8a, 0xe4, 0xb8, 0xa1, 0xa6, 0x0f, 0x6d, 0xa8, 0x99, 0xa5, 0x5b, 0xc8, 0xf5, 0x74, + 0x2e, 0x59, 0x49, 0x91, 0xef, 0x10, 0x14, 0x65, 0x64, 0x8a, 0x8c, 0x97, 0xc1, 0x90, 0x95, 0xa5, + 0x4e, 0xfa, 0xc8, 0x82, 0x04, 0xad, 0x18, 0xd5, 0x12, 0xfc, 0x39, 0x94, 0x7b, 0xbe, 0x37, 0x1e, + 0xd3, 0xde, 0x1d, 0x55, 0xd5, 0xc9, 0xc5, 0xaa, 0xde, 0xd2, 0xe7, 0xad, 0x05, 0x73, 0xf2, 0x04, + 0x41, 0x49, 0xf5, 0x0c, 0x05, 0x55, 0x94, 0x22, 0x7a, 0xeb, 0x2e, 0x99, 0x5c, 0xb6, 0x4b, 0xae, + 0x81, 0xd1, 0xf7, 0xbd, 0xc9, 0x38, 0xa8, 0xa6, 0x64, 0x41, 0x4a, 0x89, 0x5c, 0x87, 0x72, 0x18, + 0xdc, 0x11, 0xad, 0xb0, 0xb6, 0xd8, 0x0a, 0xb7, 0x7b, 0xd4, 0x65, 0xce, 0xae, 0x43, 0xfd, 0x4e, + 0x9a, 0x6f, 0x12, 0xb5, 0xc2, 0xef, 0x11, 0x54, 0x16, 0x4d, 0xf0, 0x67, 0x1a, 0x11, 0xb9, 0xbb, + 0x33, 0x47, 0xbb, 0x6b, 0x89, 0x1e, 0x12, 0x88, 0x42, 0x0d, 0x49, 0x5a, 0xbb, 0x08, 0x05, 0x4d, + 0x8d, 0x2b, 0x90, 0xda, 0xa3, 0x21, 0xc9, 0xf8, 0x90, 0xd3, 0x28, 0x2e, 0x99, 0xbc, 0xaa, 0x93, + 0x4b, 0xc9, 0x0b, 0x88, 0x53, 0xb4, 0x34, 0x77, 0x36, 0xf8, 0x02, 0xa4, 0x77, 0x7d, 0x6f, 0xb4, + 0x14, 0xf0, 0x62, 0x05, 0xfe, 0x00, 0x92, 0xcc, 0x5b, 0x0a, 0xf6, 0x24, 0xf3, 0x38, 0xea, 0x2a, + 0xf9, 0x94, 0x08, 0x4e, 0x49, 0xe4, 0x67, 0x04, 0xc7, 0xf8, 0x1a, 0x89, 0xc0, 0x95, 0xc1, 0xc4, + 0xdd, 0xc3, 0x4d, 0xa8, 0xf0, 0x9d, 0x1e, 0x38, 0x6e, 0x9f, 0x06, 0x8c, 0xfa, 0x0f, 0x9c, 0x9e, + 0x4a, 0xb3, 0xcc, 0xf5, 0xdb, 0x4a, 0xbd, 0xdd, 0xc3, 0xeb, 0x90, 0x9d, 0x04, 0xd2, 0x40, 0xe6, + 0x6c, 0x70, 0x71, 0xbb, 0x87, 0xdf, 0xd1, 0xb6, 0xe3, 0x58, 0x6b, 0xaf, 0x02, 0x81, 0xe1, 0x2d, + 0xdb, 0xf1, 0xa3, 0xea, 0x3f, 0x0b, 0x46, 0x97, 0x6f, 0x2c, 0xef, 0xcd, 0x42, 0xfb, 0x58, 0x6c, + 0x2c, 0x02, 0xb2, 0xd4, 0x34, 0xf9, 0x10, 0xf2, 0xd1, 0xea, 0x43, 0x6f, 0xa2, 0x43, 0x4f, 0x80, + 0x9c, 0x80, 0x8c, 0x4c, 0x0c, 0x43, 0xba, 0x67, 0x33, 0x5b, 0x2c, 0x29, 0x5a, 0x62, 0x4c, 0xaa, + 0xb0, 0x76, 0xd7, 0xb7, 0xdd, 0x60, 0x97, 0xfa, 0xc2, 0x28, 0xa2, 0x1f, 0x39, 0x0e, 0x2b, 0xbc, + 0x78, 0xa9, 0x1f, 0x5c, 0xf1, 0x26, 0x2e, 0x53, 0x35, 0x43, 0xce, 0xc1, 0xea, 0xbc, 0x5a, 0xb1, + 0x75, 0x15, 0x32, 0x5d, 0xae, 0x10, 0xde, 0x4b, 0x96, 0x14, 0xc8, 0x8f, 0x08, 0xf0, 0x97, 0x94, + 0x09, 0xd7, 0xdb, 0x5b, 0x81, 0xf6, 0x74, 0x19, 0xd9, 0xac, 0x3b, 0xa0, 0x7e, 0x10, 0x3e, 0x5d, + 0x42, 0xf9, 0xbf, 0x78, 0xba, 0x90, 0xf3, 0xb0, 0x32, 0x17, 0xa5, 0xca, 0xa9, 0x06, 0xb9, 0xae, + 0xd2, 0xa9, 0xeb, 0x33, 0x92, 0xff, 0x7f, 0x06, 0xf2, 0xd1, 0x03, 0x0f, 0x17, 0x20, 0x7b, 0xf5, + 0xa6, 0x75, 0x6f, 0xd3, 0xda, 0xaa, 0x24, 0x70, 0x11, 0x72, 0x9d, 0xcd, 0x2b, 0x5f, 0x09, 0x09, + 0xb5, 0x37, 0xc1, 0xe0, 0x4f, 0x5d, 0xea, 0xe3, 0x8f, 0x21, 0xcd, 0x47, 0xf8, 0x78, 0x7c, 0xbe, + 0xda, 0xeb, 0xba, 0xb6, 0xb6, 0xa8, 0x56, 0xe7, 0x90, 0x68, 0xff, 0x95, 0x82, 0x2c, 0x7f, 0xda, + 0xf0, 0x2a, 0xfe, 0x04, 0x32, 0xe2, 0x95, 0x83, 0x35, 0x73, 0xfd, 0x55, 0x58, 0x5b, 0x7f, 0x4d, + 0x1f, 0xfa, 0x79, 0x0f, 0xe1, 0xaf, 0xa1, 0x20, 0x94, 0xea, 0x2a, 0x3c, 0xb9, 0x78, 0xcd, 0xcc, + 0x79, 0x3a, 0x75, 0xc4, 0xac, 0xe6, 0xef, 0x12, 0x64, 0x04, 0x23, 0xf5, 0x68, 0xf4, 0xf7, 0x92, + 0x1e, 0xcd, 0xdc, 0xbb, 0x84, 0x24, 0xf0, 0x45, 0x48, 0x73, 0x22, 0xe9, 0x70, 0x68, 0xd7, 0x98, + 0x0e, 0x87, 0x7e, 0x87, 0x88, 0x6d, 0x3f, 0x8d, 0x6e, 0xd7, 0xf5, 0xc5, 0x26, 0x16, 0x2e, 0xaf, + 0xbe, 0x3e, 0x11, 0xed, 0x7c, 0x53, 0x5e, 0x4b, 0x21, 0x85, 0xf1, 0xa9, 0xf9, 0xad, 0x16, 0x18, + 0x5f, 0x33, 0x8f, 0x9a, 0x8e, 0x1c, 0xde, 0x80, 0x82, 0x46, 0x1f, 0x1d, 0xd6, 0xd7, 0xb9, 0xaf, + 0xc3, 0x7a, 0x08, 0xe7, 0x48, 0xa2, 0xfd, 0x0d, 0xe4, 0xc2, 0x1e, 0x83, 0x6f, 0x43, 0x79, 0xbe, + 0x3c, 0xf1, 0xff, 0xb4, 0x68, 0xe6, 0x1b, 0x57, 0xad, 0xa1, 0x4d, 0x1d, 0x5e, 0xd3, 0x89, 0x26, + 0xea, 0xdc, 0x7f, 0xf6, 0xc2, 0x4c, 0x3c, 0x7f, 0x61, 0x26, 0x5e, 0xbd, 0x30, 0xd1, 0xb7, 0x33, + 0x13, 0xfd, 0x34, 0x33, 0xd1, 0xd3, 0x99, 0x89, 0x9e, 0xcd, 0x4c, 0xf4, 0xc7, 0xcc, 0x44, 0x7f, + 0xce, 0xcc, 0xc4, 0xab, 0x99, 0x89, 0x1e, 0xbf, 0x34, 0x13, 0xcf, 0x5e, 0x9a, 0x89, 0xe7, 0x2f, + 0xcd, 0xc4, 0xfd, 0xd3, 0xfa, 0x3f, 0x47, 0xdf, 0xde, 0xb5, 0x5d, 0x7b, 0x63, 0xe8, 0xed, 0x39, + 0x1b, 0xfa, 0x3f, 0xd3, 0x1d, 0x43, 0x7c, 0xde, 0xff, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x21, + 0xc8, 0x3d, 0xb0, 0x0e, 0x00, 0x00, +} + +func (x Direction) String() string { + s, ok := Direction_name[int32(x)] + if ok { + return s + } + return strconv.Itoa(int(x)) +} +func (this *PushRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PushRequest) + if !ok { + that2, ok := that.(PushRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Streams) != len(that1.Streams) { + return false + } + for i := range this.Streams { + if !this.Streams[i].Equal(that1.Streams[i]) { + return false + } + } + return true +} +func (this *PushResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PushResponse) + if !ok { + that2, ok := that.(PushResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + return true +} +func (this *QueryRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryRequest) + if !ok { + that2, ok := that.(QueryRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Selector != that1.Selector { + return false + } + if this.Limit != that1.Limit { + return false + } + if !this.Start.Equal(that1.Start) { + return false + } + if !this.End.Equal(that1.End) { + return false + } + if this.Direction != that1.Direction { + return false + } + if len(this.Shards) != len(that1.Shards) { + return false + } + for i := range this.Shards { + if this.Shards[i] != that1.Shards[i] { + return false + } + } + return true +} +func (this *SampleQueryRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*SampleQueryRequest) + if !ok { + that2, ok := that.(SampleQueryRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Selector != that1.Selector { + return false + } + if !this.Start.Equal(that1.Start) { + return false + } + if !this.End.Equal(that1.End) { + return false + } + if len(this.Shards) != len(that1.Shards) { + return false + } + for i := range this.Shards { + if this.Shards[i] != that1.Shards[i] { + return false + } + } + return true +} +func (this *SampleQueryResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*SampleQueryResponse) + if !ok { + that2, ok := that.(SampleQueryResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Series) != len(that1.Series) { + return false + } + for i := range this.Series { + if !this.Series[i].Equal(that1.Series[i]) { + return false + } + } + return true +} +func (this *QueryResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*QueryResponse) + if !ok { + that2, ok := that.(QueryResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Streams) != len(that1.Streams) { + return false + } + for i := range this.Streams { + if !this.Streams[i].Equal(that1.Streams[i]) { + return false + } + } + return true +} +func (this *LabelRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LabelRequest) + if !ok { + that2, ok := that.(LabelRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Name != that1.Name { + return false + } + if this.Values != that1.Values { + return false + } + if that1.Start == nil { + if this.Start != nil { + return false + } + } else if !this.Start.Equal(*that1.Start) { + return false + } + if that1.End == nil { + if this.End != nil { + return false + } + } else if !this.End.Equal(*that1.End) { + return false + } + return true +} +func (this *LabelResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LabelResponse) + if !ok { + that2, ok := that.(LabelResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Values) != len(that1.Values) { + return false + } + for i := range this.Values { + if this.Values[i] != that1.Values[i] { + return false + } + } + return true +} +func (this *StreamAdapter) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*StreamAdapter) + if !ok { + that2, ok := that.(StreamAdapter) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Labels != that1.Labels { + return false + } + if len(this.Entries) != len(that1.Entries) { + return false + } + for i := range this.Entries { + if !this.Entries[i].Equal(&that1.Entries[i]) { + return false + } + } + return true +} +func (this *EntryAdapter) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*EntryAdapter) + if !ok { + that2, ok := that.(EntryAdapter) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Timestamp.Equal(that1.Timestamp) { + return false + } + if this.Line != that1.Line { + return false + } + return true +} +func (this *Sample) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Sample) + if !ok { + that2, ok := that.(Sample) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Timestamp != that1.Timestamp { + return false + } + if this.Value != that1.Value { + return false + } + if this.Hash != that1.Hash { + return false + } + return true +} +func (this *Series) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Series) + if !ok { + that2, ok := that.(Series) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Labels != that1.Labels { + return false + } + if len(this.Samples) != len(that1.Samples) { + return false + } + for i := range this.Samples { + if !this.Samples[i].Equal(&that1.Samples[i]) { + return false + } + } + return true +} +func (this *TailRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*TailRequest) + if !ok { + that2, ok := that.(TailRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Query != that1.Query { + return false + } + if this.DelayFor != that1.DelayFor { + return false + } + if this.Limit != that1.Limit { + return false + } + if !this.Start.Equal(that1.Start) { + return false + } + return true +} +func (this *TailResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*TailResponse) + if !ok { + that2, ok := that.(TailResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if that1.Stream == nil { + if this.Stream != nil { + return false + } + } else if !this.Stream.Equal(*that1.Stream) { + return false + } + if len(this.DroppedStreams) != len(that1.DroppedStreams) { + return false + } + for i := range this.DroppedStreams { + if !this.DroppedStreams[i].Equal(that1.DroppedStreams[i]) { + return false + } + } + return true +} +func (this *SeriesRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*SeriesRequest) + if !ok { + that2, ok := that.(SeriesRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Start.Equal(that1.Start) { + return false + } + if !this.End.Equal(that1.End) { + return false + } + if len(this.Groups) != len(that1.Groups) { + return false + } + for i := range this.Groups { + if this.Groups[i] != that1.Groups[i] { + return false + } + } + return true +} +func (this *SeriesResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*SeriesResponse) + if !ok { + that2, ok := that.(SeriesResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Series) != len(that1.Series) { + return false + } + for i := range this.Series { + if !this.Series[i].Equal(&that1.Series[i]) { + return false + } + } + return true +} +func (this *SeriesIdentifier) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*SeriesIdentifier) + if !ok { + that2, ok := that.(SeriesIdentifier) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Labels) != len(that1.Labels) { + return false + } + for i := range this.Labels { + if this.Labels[i] != that1.Labels[i] { + return false + } + } + return true +} +func (this *DroppedStream) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*DroppedStream) + if !ok { + that2, ok := that.(DroppedStream) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.From.Equal(that1.From) { + return false + } + if !this.To.Equal(that1.To) { + return false + } + if this.Labels != that1.Labels { + return false + } + return true +} +func (this *TimeSeriesChunk) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*TimeSeriesChunk) + if !ok { + that2, ok := that.(TimeSeriesChunk) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.FromIngesterId != that1.FromIngesterId { + return false + } + if this.UserId != that1.UserId { + return false + } + if len(this.Labels) != len(that1.Labels) { + return false + } + for i := range this.Labels { + if !this.Labels[i].Equal(that1.Labels[i]) { + return false + } + } + if len(this.Chunks) != len(that1.Chunks) { + return false + } + for i := range this.Chunks { + if !this.Chunks[i].Equal(that1.Chunks[i]) { + return false + } + } + return true +} +func (this *LabelPair) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LabelPair) + if !ok { + that2, ok := that.(LabelPair) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Name != that1.Name { + return false + } + if this.Value != that1.Value { + return false + } + return true +} +func (this *Chunk) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Chunk) + if !ok { + that2, ok := that.(Chunk) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.Data, that1.Data) { + return false + } + return true +} +func (this *TransferChunksResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*TransferChunksResponse) + if !ok { + that2, ok := that.(TransferChunksResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + return true +} +func (this *TailersCountRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*TailersCountRequest) + if !ok { + that2, ok := that.(TailersCountRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + return true +} +func (this *TailersCountResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*TailersCountResponse) + if !ok { + that2, ok := that.(TailersCountResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Count != that1.Count { + return false + } + return true +} +func (this *GetChunkIDsRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*GetChunkIDsRequest) + if !ok { + that2, ok := that.(GetChunkIDsRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Matchers != that1.Matchers { + return false + } + if !this.Start.Equal(that1.Start) { + return false + } + if !this.End.Equal(that1.End) { + return false + } + return true +} +func (this *GetChunkIDsResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*GetChunkIDsResponse) + if !ok { + that2, ok := that.(GetChunkIDsResponse) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.ChunkIDs) != len(that1.ChunkIDs) { + return false + } + for i := range this.ChunkIDs { + if this.ChunkIDs[i] != that1.ChunkIDs[i] { + return false + } + } + return true +} +func (this *PushRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.PushRequest{") + s = append(s, "Streams: "+fmt.Sprintf("%#v", this.Streams)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *PushResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 4) + s = append(s, "&logproto.PushResponse{") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *QueryRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 10) + s = append(s, "&logproto.QueryRequest{") + s = append(s, "Selector: "+fmt.Sprintf("%#v", this.Selector)+",\n") + s = append(s, "Limit: "+fmt.Sprintf("%#v", this.Limit)+",\n") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "End: "+fmt.Sprintf("%#v", this.End)+",\n") + s = append(s, "Direction: "+fmt.Sprintf("%#v", this.Direction)+",\n") + s = append(s, "Shards: "+fmt.Sprintf("%#v", this.Shards)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SampleQueryRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&logproto.SampleQueryRequest{") + s = append(s, "Selector: "+fmt.Sprintf("%#v", this.Selector)+",\n") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "End: "+fmt.Sprintf("%#v", this.End)+",\n") + s = append(s, "Shards: "+fmt.Sprintf("%#v", this.Shards)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SampleQueryResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.SampleQueryResponse{") + s = append(s, "Series: "+fmt.Sprintf("%#v", this.Series)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *QueryResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.QueryResponse{") + s = append(s, "Streams: "+fmt.Sprintf("%#v", this.Streams)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *LabelRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&logproto.LabelRequest{") + s = append(s, "Name: "+fmt.Sprintf("%#v", this.Name)+",\n") + s = append(s, "Values: "+fmt.Sprintf("%#v", this.Values)+",\n") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "End: "+fmt.Sprintf("%#v", this.End)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *LabelResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.LabelResponse{") + s = append(s, "Values: "+fmt.Sprintf("%#v", this.Values)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *StreamAdapter) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&logproto.StreamAdapter{") + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") + if this.Entries != nil { + vs := make([]*EntryAdapter, len(this.Entries)) + for i := range vs { + vs[i] = &this.Entries[i] + } + s = append(s, "Entries: "+fmt.Sprintf("%#v", vs)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *EntryAdapter) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&logproto.EntryAdapter{") + s = append(s, "Timestamp: "+fmt.Sprintf("%#v", this.Timestamp)+",\n") + s = append(s, "Line: "+fmt.Sprintf("%#v", this.Line)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Sample) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&logproto.Sample{") + s = append(s, "Timestamp: "+fmt.Sprintf("%#v", this.Timestamp)+",\n") + s = append(s, "Value: "+fmt.Sprintf("%#v", this.Value)+",\n") + s = append(s, "Hash: "+fmt.Sprintf("%#v", this.Hash)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Series) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&logproto.Series{") + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") + if this.Samples != nil { + vs := make([]*Sample, len(this.Samples)) + for i := range vs { + vs[i] = &this.Samples[i] + } + s = append(s, "Samples: "+fmt.Sprintf("%#v", vs)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TailRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&logproto.TailRequest{") + s = append(s, "Query: "+fmt.Sprintf("%#v", this.Query)+",\n") + s = append(s, "DelayFor: "+fmt.Sprintf("%#v", this.DelayFor)+",\n") + s = append(s, "Limit: "+fmt.Sprintf("%#v", this.Limit)+",\n") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TailResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&logproto.TailResponse{") + s = append(s, "Stream: "+fmt.Sprintf("%#v", this.Stream)+",\n") + if this.DroppedStreams != nil { + s = append(s, "DroppedStreams: "+fmt.Sprintf("%#v", this.DroppedStreams)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SeriesRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&logproto.SeriesRequest{") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "End: "+fmt.Sprintf("%#v", this.End)+",\n") + s = append(s, "Groups: "+fmt.Sprintf("%#v", this.Groups)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SeriesResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.SeriesResponse{") + if this.Series != nil { + vs := make([]*SeriesIdentifier, len(this.Series)) + for i := range vs { + vs[i] = &this.Series[i] + } + s = append(s, "Series: "+fmt.Sprintf("%#v", vs)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *SeriesIdentifier) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.SeriesIdentifier{") + keysForLabels := make([]string, 0, len(this.Labels)) + for k, _ := range this.Labels { + keysForLabels = append(keysForLabels, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) + mapStringForLabels := "map[string]string{" + for _, k := range keysForLabels { + mapStringForLabels += fmt.Sprintf("%#v: %#v,", k, this.Labels[k]) + } + mapStringForLabels += "}" + if this.Labels != nil { + s = append(s, "Labels: "+mapStringForLabels+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *DroppedStream) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&logproto.DroppedStream{") + s = append(s, "From: "+fmt.Sprintf("%#v", this.From)+",\n") + s = append(s, "To: "+fmt.Sprintf("%#v", this.To)+",\n") + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TimeSeriesChunk) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 8) + s = append(s, "&logproto.TimeSeriesChunk{") + s = append(s, "FromIngesterId: "+fmt.Sprintf("%#v", this.FromIngesterId)+",\n") + s = append(s, "UserId: "+fmt.Sprintf("%#v", this.UserId)+",\n") + if this.Labels != nil { + s = append(s, "Labels: "+fmt.Sprintf("%#v", this.Labels)+",\n") + } + if this.Chunks != nil { + s = append(s, "Chunks: "+fmt.Sprintf("%#v", this.Chunks)+",\n") + } + s = append(s, "}") + return strings.Join(s, "") +} +func (this *LabelPair) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 6) + s = append(s, "&logproto.LabelPair{") + s = append(s, "Name: "+fmt.Sprintf("%#v", this.Name)+",\n") + s = append(s, "Value: "+fmt.Sprintf("%#v", this.Value)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *Chunk) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.Chunk{") + s = append(s, "Data: "+fmt.Sprintf("%#v", this.Data)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TransferChunksResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 4) + s = append(s, "&logproto.TransferChunksResponse{") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TailersCountRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 4) + s = append(s, "&logproto.TailersCountRequest{") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *TailersCountResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.TailersCountResponse{") + s = append(s, "Count: "+fmt.Sprintf("%#v", this.Count)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *GetChunkIDsRequest) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&logproto.GetChunkIDsRequest{") + s = append(s, "Matchers: "+fmt.Sprintf("%#v", this.Matchers)+",\n") + s = append(s, "Start: "+fmt.Sprintf("%#v", this.Start)+",\n") + s = append(s, "End: "+fmt.Sprintf("%#v", this.End)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func (this *GetChunkIDsResponse) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 5) + s = append(s, "&logproto.GetChunkIDsResponse{") + s = append(s, "ChunkIDs: "+fmt.Sprintf("%#v", this.ChunkIDs)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} +func valueToGoStringLogproto(v interface{}, typ string) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// PusherClient is the client API for Pusher service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type PusherClient interface { + Push(ctx context.Context, in *PushRequest, opts ...grpc.CallOption) (*PushResponse, error) +} + +type pusherClient struct { + cc *grpc.ClientConn +} + +func NewPusherClient(cc *grpc.ClientConn) PusherClient { + return &pusherClient{cc} +} + +func (c *pusherClient) Push(ctx context.Context, in *PushRequest, opts ...grpc.CallOption) (*PushResponse, error) { + out := new(PushResponse) + err := c.cc.Invoke(ctx, "/logproto.Pusher/Push", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PusherServer is the server API for Pusher service. +type PusherServer interface { + Push(context.Context, *PushRequest) (*PushResponse, error) +} + +func RegisterPusherServer(s *grpc.Server, srv PusherServer) { + s.RegisterService(&_Pusher_serviceDesc, srv) +} + +func _Pusher_Push_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PushRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PusherServer).Push(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/logproto.Pusher/Push", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PusherServer).Push(ctx, req.(*PushRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Pusher_serviceDesc = grpc.ServiceDesc{ + ServiceName: "logproto.Pusher", + HandlerType: (*PusherServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Push", + Handler: _Pusher_Push_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pkg/logproto/logproto.proto", +} + +// QuerierClient is the client API for Querier service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QuerierClient interface { + Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (Querier_QueryClient, error) + QuerySample(ctx context.Context, in *SampleQueryRequest, opts ...grpc.CallOption) (Querier_QuerySampleClient, error) + Label(ctx context.Context, in *LabelRequest, opts ...grpc.CallOption) (*LabelResponse, error) + Tail(ctx context.Context, in *TailRequest, opts ...grpc.CallOption) (Querier_TailClient, error) + Series(ctx context.Context, in *SeriesRequest, opts ...grpc.CallOption) (*SeriesResponse, error) + TailersCount(ctx context.Context, in *TailersCountRequest, opts ...grpc.CallOption) (*TailersCountResponse, error) + GetChunkIDs(ctx context.Context, in *GetChunkIDsRequest, opts ...grpc.CallOption) (*GetChunkIDsResponse, error) +} + +type querierClient struct { + cc *grpc.ClientConn +} + +func NewQuerierClient(cc *grpc.ClientConn) QuerierClient { + return &querierClient{cc} +} + +func (c *querierClient) Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (Querier_QueryClient, error) { + stream, err := c.cc.NewStream(ctx, &_Querier_serviceDesc.Streams[0], "/logproto.Querier/Query", opts...) + if err != nil { + return nil, err + } + x := &querierQueryClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Querier_QueryClient interface { + Recv() (*QueryResponse, error) + grpc.ClientStream +} + +type querierQueryClient struct { + grpc.ClientStream +} + +func (x *querierQueryClient) Recv() (*QueryResponse, error) { + m := new(QueryResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *querierClient) QuerySample(ctx context.Context, in *SampleQueryRequest, opts ...grpc.CallOption) (Querier_QuerySampleClient, error) { + stream, err := c.cc.NewStream(ctx, &_Querier_serviceDesc.Streams[1], "/logproto.Querier/QuerySample", opts...) + if err != nil { + return nil, err + } + x := &querierQuerySampleClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Querier_QuerySampleClient interface { + Recv() (*SampleQueryResponse, error) + grpc.ClientStream +} + +type querierQuerySampleClient struct { + grpc.ClientStream +} + +func (x *querierQuerySampleClient) Recv() (*SampleQueryResponse, error) { + m := new(SampleQueryResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *querierClient) Label(ctx context.Context, in *LabelRequest, opts ...grpc.CallOption) (*LabelResponse, error) { + out := new(LabelResponse) + err := c.cc.Invoke(ctx, "/logproto.Querier/Label", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *querierClient) Tail(ctx context.Context, in *TailRequest, opts ...grpc.CallOption) (Querier_TailClient, error) { + stream, err := c.cc.NewStream(ctx, &_Querier_serviceDesc.Streams[2], "/logproto.Querier/Tail", opts...) + if err != nil { + return nil, err + } + x := &querierTailClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Querier_TailClient interface { + Recv() (*TailResponse, error) + grpc.ClientStream +} + +type querierTailClient struct { + grpc.ClientStream +} + +func (x *querierTailClient) Recv() (*TailResponse, error) { + m := new(TailResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *querierClient) Series(ctx context.Context, in *SeriesRequest, opts ...grpc.CallOption) (*SeriesResponse, error) { + out := new(SeriesResponse) + err := c.cc.Invoke(ctx, "/logproto.Querier/Series", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *querierClient) TailersCount(ctx context.Context, in *TailersCountRequest, opts ...grpc.CallOption) (*TailersCountResponse, error) { + out := new(TailersCountResponse) + err := c.cc.Invoke(ctx, "/logproto.Querier/TailersCount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *querierClient) GetChunkIDs(ctx context.Context, in *GetChunkIDsRequest, opts ...grpc.CallOption) (*GetChunkIDsResponse, error) { + out := new(GetChunkIDsResponse) + err := c.cc.Invoke(ctx, "/logproto.Querier/GetChunkIDs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QuerierServer is the server API for Querier service. +type QuerierServer interface { + Query(*QueryRequest, Querier_QueryServer) error + QuerySample(*SampleQueryRequest, Querier_QuerySampleServer) error + Label(context.Context, *LabelRequest) (*LabelResponse, error) + Tail(*TailRequest, Querier_TailServer) error + Series(context.Context, *SeriesRequest) (*SeriesResponse, error) + TailersCount(context.Context, *TailersCountRequest) (*TailersCountResponse, error) + GetChunkIDs(context.Context, *GetChunkIDsRequest) (*GetChunkIDsResponse, error) +} + +func RegisterQuerierServer(s *grpc.Server, srv QuerierServer) { + s.RegisterService(&_Querier_serviceDesc, srv) +} + +func _Querier_Query_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(QueryRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QuerierServer).Query(m, &querierQueryServer{stream}) +} + +type Querier_QueryServer interface { + Send(*QueryResponse) error + grpc.ServerStream +} + +type querierQueryServer struct { + grpc.ServerStream +} + +func (x *querierQueryServer) Send(m *QueryResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Querier_QuerySample_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SampleQueryRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QuerierServer).QuerySample(m, &querierQuerySampleServer{stream}) +} + +type Querier_QuerySampleServer interface { + Send(*SampleQueryResponse) error + grpc.ServerStream +} + +type querierQuerySampleServer struct { + grpc.ServerStream +} + +func (x *querierQuerySampleServer) Send(m *SampleQueryResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Querier_Label_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LabelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuerierServer).Label(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/logproto.Querier/Label", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuerierServer).Label(ctx, req.(*LabelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Querier_Tail_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(TailRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QuerierServer).Tail(m, &querierTailServer{stream}) +} + +type Querier_TailServer interface { + Send(*TailResponse) error + grpc.ServerStream +} + +type querierTailServer struct { + grpc.ServerStream +} + +func (x *querierTailServer) Send(m *TailResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _Querier_Series_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SeriesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuerierServer).Series(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/logproto.Querier/Series", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuerierServer).Series(ctx, req.(*SeriesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Querier_TailersCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TailersCountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuerierServer).TailersCount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/logproto.Querier/TailersCount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuerierServer).TailersCount(ctx, req.(*TailersCountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Querier_GetChunkIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetChunkIDsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QuerierServer).GetChunkIDs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/logproto.Querier/GetChunkIDs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QuerierServer).GetChunkIDs(ctx, req.(*GetChunkIDsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Querier_serviceDesc = grpc.ServiceDesc{ + ServiceName: "logproto.Querier", + HandlerType: (*QuerierServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Label", + Handler: _Querier_Label_Handler, + }, + { + MethodName: "Series", + Handler: _Querier_Series_Handler, + }, + { + MethodName: "TailersCount", + Handler: _Querier_TailersCount_Handler, + }, + { + MethodName: "GetChunkIDs", + Handler: _Querier_GetChunkIDs_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Query", + Handler: _Querier_Query_Handler, + ServerStreams: true, + }, + { + StreamName: "QuerySample", + Handler: _Querier_QuerySample_Handler, + ServerStreams: true, + }, + { + StreamName: "Tail", + Handler: _Querier_Tail_Handler, + ServerStreams: true, + }, + }, + Metadata: "pkg/logproto/logproto.proto", +} + +// IngesterClient is the client API for Ingester service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type IngesterClient interface { + TransferChunks(ctx context.Context, opts ...grpc.CallOption) (Ingester_TransferChunksClient, error) +} + +type ingesterClient struct { + cc *grpc.ClientConn +} + +func NewIngesterClient(cc *grpc.ClientConn) IngesterClient { + return &ingesterClient{cc} +} + +func (c *ingesterClient) TransferChunks(ctx context.Context, opts ...grpc.CallOption) (Ingester_TransferChunksClient, error) { + stream, err := c.cc.NewStream(ctx, &_Ingester_serviceDesc.Streams[0], "/logproto.Ingester/TransferChunks", opts...) + if err != nil { + return nil, err + } + x := &ingesterTransferChunksClient{stream} + return x, nil +} + +type Ingester_TransferChunksClient interface { + Send(*TimeSeriesChunk) error + CloseAndRecv() (*TransferChunksResponse, error) + grpc.ClientStream +} + +type ingesterTransferChunksClient struct { + grpc.ClientStream +} + +func (x *ingesterTransferChunksClient) Send(m *TimeSeriesChunk) error { + return x.ClientStream.SendMsg(m) +} + +func (x *ingesterTransferChunksClient) CloseAndRecv() (*TransferChunksResponse, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new(TransferChunksResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// IngesterServer is the server API for Ingester service. +type IngesterServer interface { + TransferChunks(Ingester_TransferChunksServer) error +} + +func RegisterIngesterServer(s *grpc.Server, srv IngesterServer) { + s.RegisterService(&_Ingester_serviceDesc, srv) +} + +func _Ingester_TransferChunks_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(IngesterServer).TransferChunks(&ingesterTransferChunksServer{stream}) +} + +type Ingester_TransferChunksServer interface { + SendAndClose(*TransferChunksResponse) error + Recv() (*TimeSeriesChunk, error) + grpc.ServerStream +} + +type ingesterTransferChunksServer struct { + grpc.ServerStream +} + +func (x *ingesterTransferChunksServer) SendAndClose(m *TransferChunksResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *ingesterTransferChunksServer) Recv() (*TimeSeriesChunk, error) { + m := new(TimeSeriesChunk) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _Ingester_serviceDesc = grpc.ServiceDesc{ + ServiceName: "logproto.Ingester", + HandlerType: (*IngesterServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "TransferChunks", + Handler: _Ingester_TransferChunks_Handler, + ClientStreams: true, + }, + }, + Metadata: "pkg/logproto/logproto.proto", +} + +func (m *PushRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PushRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Streams) > 0 { + for _, msg := range m.Streams { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *PushResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PushResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *QueryRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Selector) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Selector))) + i += copy(dAtA[i:], m.Selector) + } + if m.Limit != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Limit)) + } + dAtA[i] = 0x1a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Start))) + n1, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + dAtA[i] = 0x22 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.End))) + n2, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.End, dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + if m.Direction != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Direction)) + } + if len(m.Shards) > 0 { + for _, s := range m.Shards { + dAtA[i] = 0x3a + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *SampleQueryRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SampleQueryRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Selector) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Selector))) + i += copy(dAtA[i:], m.Selector) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Start))) + n3, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + dAtA[i] = 0x1a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.End))) + n4, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.End, dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + if len(m.Shards) > 0 { + for _, s := range m.Shards { + dAtA[i] = 0x22 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *SampleQueryResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SampleQueryResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Series) > 0 { + for _, msg := range m.Series { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *QueryResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Streams) > 0 { + for _, msg := range m.Streams { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *LabelRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LabelRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if m.Values { + dAtA[i] = 0x10 + i++ + if m.Values { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + if m.Start != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.Start))) + n5, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Start, dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + if m.End != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.End))) + n6, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.End, dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + } + return i, nil +} + +func (m *LabelResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LabelResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Values) > 0 { + for _, s := range m.Values { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *StreamAdapter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StreamAdapter) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Labels) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Labels))) + i += copy(dAtA[i:], m.Labels) + } + if len(m.Entries) > 0 { + for _, msg := range m.Entries { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *EntryAdapter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EntryAdapter) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp))) + n7, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i:]) + if err != nil { + return 0, err + } + i += n7 + if len(m.Line) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Line))) + i += copy(dAtA[i:], m.Line) + } + return i, nil +} + +func (m *Sample) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Sample) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Timestamp != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Timestamp)) + } + if m.Value != 0 { + dAtA[i] = 0x11 + i++ + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.Value)))) + i += 8 + } + if m.Hash != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Hash)) + } + return i, nil +} + +func (m *Series) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Series) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Labels) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Labels))) + i += copy(dAtA[i:], m.Labels) + } + if len(m.Samples) > 0 { + for _, msg := range m.Samples { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *TailRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TailRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Query) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Query))) + i += copy(dAtA[i:], m.Query) + } + if m.DelayFor != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.DelayFor)) + } + if m.Limit != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Limit)) + } + dAtA[i] = 0x2a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Start))) + n8, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i:]) + if err != nil { + return 0, err + } + i += n8 + return i, nil +} + +func (m *TailResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TailResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Stream != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Stream.Size())) + n9, err := m.Stream.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n9 + } + if len(m.DroppedStreams) > 0 { + for _, msg := range m.DroppedStreams { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *SeriesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SeriesRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Start))) + n10, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i:]) + if err != nil { + return 0, err + } + i += n10 + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.End))) + n11, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.End, dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + if len(m.Groups) > 0 { + for _, s := range m.Groups { + dAtA[i] = 0x1a + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func (m *SeriesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SeriesResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Series) > 0 { + for _, msg := range m.Series { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *SeriesIdentifier) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SeriesIdentifier) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Labels) > 0 { + for k, _ := range m.Labels { + dAtA[i] = 0xa + i++ + v := m.Labels[k] + mapSize := 1 + len(k) + sovLogproto(uint64(len(k))) + 1 + len(v) + sovLogproto(uint64(len(v))) + i = encodeVarintLogproto(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } + return i, nil +} + +func (m *DroppedStream) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DroppedStream) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.From))) + n12, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.From, dAtA[i:]) + if err != nil { + return 0, err + } + i += n12 + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.To))) + n13, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.To, dAtA[i:]) + if err != nil { + return 0, err + } + i += n13 + if len(m.Labels) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Labels))) + i += copy(dAtA[i:], m.Labels) + } + return i, nil +} + +func (m *TimeSeriesChunk) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TimeSeriesChunk) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.FromIngesterId) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.FromIngesterId))) + i += copy(dAtA[i:], m.FromIngesterId) + } + if len(m.UserId) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.UserId))) + i += copy(dAtA[i:], m.UserId) + } + if len(m.Labels) > 0 { + for _, msg := range m.Labels { + dAtA[i] = 0x1a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Chunks) > 0 { + for _, msg := range m.Chunks { + dAtA[i] = 0x22 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *LabelPair) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LabelPair) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + return i, nil +} + +func (m *Chunk) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Chunk) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Data) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + return i, nil +} + +func (m *TransferChunksResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TransferChunksResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *TailersCountRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TailersCountRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *TailersCountResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TailersCountResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Count != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(m.Count)) + } + return i, nil +} + +func (m *GetChunkIDsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetChunkIDsRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Matchers) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Matchers))) + i += copy(dAtA[i:], m.Matchers) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Start))) + n14, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i:]) + if err != nil { + return 0, err + } + i += n14 + dAtA[i] = 0x1a + i++ + i = encodeVarintLogproto(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.End))) + n15, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.End, dAtA[i:]) + if err != nil { + return 0, err + } + i += n15 + return i, nil +} + +func (m *GetChunkIDsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetChunkIDsResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ChunkIDs) > 0 { + for _, s := range m.ChunkIDs { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func encodeVarintLogproto(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *PushRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Streams) > 0 { + for _, e := range m.Streams { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *PushResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Selector) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if m.Limit != 0 { + n += 1 + sovLogproto(uint64(m.Limit)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovLogproto(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) + n += 1 + l + sovLogproto(uint64(l)) + if m.Direction != 0 { + n += 1 + sovLogproto(uint64(m.Direction)) + } + if len(m.Shards) > 0 { + for _, s := range m.Shards { + l = len(s) + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *SampleQueryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Selector) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovLogproto(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) + n += 1 + l + sovLogproto(uint64(l)) + if len(m.Shards) > 0 { + for _, s := range m.Shards { + l = len(s) + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *SampleQueryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Series) > 0 { + for _, e := range m.Series { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *QueryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Streams) > 0 { + for _, e := range m.Streams { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *LabelRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if m.Values { + n += 2 + } + if m.Start != nil { + l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.Start) + n += 1 + l + sovLogproto(uint64(l)) + } + if m.End != nil { + l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.End) + n += 1 + l + sovLogproto(uint64(l)) + } + return n +} + +func (m *LabelResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Values) > 0 { + for _, s := range m.Values { + l = len(s) + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *StreamAdapter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Labels) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *EntryAdapter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) + n += 1 + l + sovLogproto(uint64(l)) + l = len(m.Line) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + return n +} + +func (m *Sample) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Timestamp != 0 { + n += 1 + sovLogproto(uint64(m.Timestamp)) + } + if m.Value != 0 { + n += 9 + } + if m.Hash != 0 { + n += 1 + sovLogproto(uint64(m.Hash)) + } + return n +} + +func (m *Series) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Labels) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if len(m.Samples) > 0 { + for _, e := range m.Samples { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *TailRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Query) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if m.DelayFor != 0 { + n += 1 + sovLogproto(uint64(m.DelayFor)) + } + if m.Limit != 0 { + n += 1 + sovLogproto(uint64(m.Limit)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovLogproto(uint64(l)) + return n +} + +func (m *TailResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Stream != nil { + l = m.Stream.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + if len(m.DroppedStreams) > 0 { + for _, e := range m.DroppedStreams { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *SeriesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovLogproto(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) + n += 1 + l + sovLogproto(uint64(l)) + if len(m.Groups) > 0 { + for _, s := range m.Groups { + l = len(s) + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *SeriesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Series) > 0 { + for _, e := range m.Series { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *SeriesIdentifier) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Labels) > 0 { + for k, v := range m.Labels { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovLogproto(uint64(len(k))) + 1 + len(v) + sovLogproto(uint64(len(v))) + n += mapEntrySize + 1 + sovLogproto(uint64(mapEntrySize)) + } + } + return n +} + +func (m *DroppedStream) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.From) + n += 1 + l + sovLogproto(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.To) + n += 1 + l + sovLogproto(uint64(l)) + l = len(m.Labels) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + return n +} + +func (m *TimeSeriesChunk) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FromIngesterId) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + l = len(m.UserId) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if len(m.Labels) > 0 { + for _, e := range m.Labels { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + if len(m.Chunks) > 0 { + for _, e := range m.Chunks { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *LabelPair) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + return n +} + +func (m *Chunk) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + return n +} + +func (m *TransferChunksResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *TailersCountRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *TailersCountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Count != 0 { + n += 1 + sovLogproto(uint64(m.Count)) + } + return n +} + +func (m *GetChunkIDsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Matchers) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Start) + n += 1 + l + sovLogproto(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.End) + n += 1 + l + sovLogproto(uint64(l)) + return n +} + +func (m *GetChunkIDsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ChunkIDs) > 0 { + for _, s := range m.ChunkIDs { + l = len(s) + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func sovLogproto(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozLogproto(x uint64) (n int) { + return sovLogproto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *PushRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PushRequest{`, + `Streams:` + fmt.Sprintf("%v", this.Streams) + `,`, + `}`, + }, "") + return s +} +func (this *PushResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PushResponse{`, + `}`, + }, "") + return s +} +func (this *QueryRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QueryRequest{`, + `Selector:` + fmt.Sprintf("%v", this.Selector) + `,`, + `Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, + `Start:` + strings.Replace(strings.Replace(this.Start.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `End:` + strings.Replace(strings.Replace(this.End.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `Direction:` + fmt.Sprintf("%v", this.Direction) + `,`, + `Shards:` + fmt.Sprintf("%v", this.Shards) + `,`, + `}`, + }, "") + return s +} +func (this *SampleQueryRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SampleQueryRequest{`, + `Selector:` + fmt.Sprintf("%v", this.Selector) + `,`, + `Start:` + strings.Replace(strings.Replace(this.Start.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `End:` + strings.Replace(strings.Replace(this.End.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `Shards:` + fmt.Sprintf("%v", this.Shards) + `,`, + `}`, + }, "") + return s +} +func (this *SampleQueryResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SampleQueryResponse{`, + `Series:` + fmt.Sprintf("%v", this.Series) + `,`, + `}`, + }, "") + return s +} +func (this *QueryResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&QueryResponse{`, + `Streams:` + fmt.Sprintf("%v", this.Streams) + `,`, + `}`, + }, "") + return s +} +func (this *LabelRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LabelRequest{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Values:` + fmt.Sprintf("%v", this.Values) + `,`, + `Start:` + strings.Replace(fmt.Sprintf("%v", this.Start), "Timestamp", "types.Timestamp", 1) + `,`, + `End:` + strings.Replace(fmt.Sprintf("%v", this.End), "Timestamp", "types.Timestamp", 1) + `,`, + `}`, + }, "") + return s +} +func (this *LabelResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LabelResponse{`, + `Values:` + fmt.Sprintf("%v", this.Values) + `,`, + `}`, + }, "") + return s +} +func (this *StreamAdapter) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&StreamAdapter{`, + `Labels:` + fmt.Sprintf("%v", this.Labels) + `,`, + `Entries:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Entries), "EntryAdapter", "EntryAdapter", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *EntryAdapter) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&EntryAdapter{`, + `Timestamp:` + strings.Replace(strings.Replace(this.Timestamp.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `Line:` + fmt.Sprintf("%v", this.Line) + `,`, + `}`, + }, "") + return s +} +func (this *Sample) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Sample{`, + `Timestamp:` + fmt.Sprintf("%v", this.Timestamp) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `Hash:` + fmt.Sprintf("%v", this.Hash) + `,`, + `}`, + }, "") + return s +} +func (this *Series) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Series{`, + `Labels:` + fmt.Sprintf("%v", this.Labels) + `,`, + `Samples:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Samples), "Sample", "Sample", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *TailRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TailRequest{`, + `Query:` + fmt.Sprintf("%v", this.Query) + `,`, + `DelayFor:` + fmt.Sprintf("%v", this.DelayFor) + `,`, + `Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, + `Start:` + strings.Replace(strings.Replace(this.Start.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *TailResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TailResponse{`, + `Stream:` + fmt.Sprintf("%v", this.Stream) + `,`, + `DroppedStreams:` + strings.Replace(fmt.Sprintf("%v", this.DroppedStreams), "DroppedStream", "DroppedStream", 1) + `,`, + `}`, + }, "") + return s +} +func (this *SeriesRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SeriesRequest{`, + `Start:` + strings.Replace(strings.Replace(this.Start.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `End:` + strings.Replace(strings.Replace(this.End.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `Groups:` + fmt.Sprintf("%v", this.Groups) + `,`, + `}`, + }, "") + return s +} +func (this *SeriesResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SeriesResponse{`, + `Series:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Series), "SeriesIdentifier", "SeriesIdentifier", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *SeriesIdentifier) String() string { + if this == nil { + return "nil" + } + keysForLabels := make([]string, 0, len(this.Labels)) + for k, _ := range this.Labels { + keysForLabels = append(keysForLabels, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForLabels) + mapStringForLabels := "map[string]string{" + for _, k := range keysForLabels { + mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k]) + } + mapStringForLabels += "}" + s := strings.Join([]string{`&SeriesIdentifier{`, + `Labels:` + mapStringForLabels + `,`, + `}`, + }, "") + return s +} +func (this *DroppedStream) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DroppedStream{`, + `From:` + strings.Replace(strings.Replace(this.From.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `To:` + strings.Replace(strings.Replace(this.To.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `Labels:` + fmt.Sprintf("%v", this.Labels) + `,`, + `}`, + }, "") + return s +} +func (this *TimeSeriesChunk) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TimeSeriesChunk{`, + `FromIngesterId:` + fmt.Sprintf("%v", this.FromIngesterId) + `,`, + `UserId:` + fmt.Sprintf("%v", this.UserId) + `,`, + `Labels:` + strings.Replace(fmt.Sprintf("%v", this.Labels), "LabelPair", "LabelPair", 1) + `,`, + `Chunks:` + strings.Replace(fmt.Sprintf("%v", this.Chunks), "Chunk", "Chunk", 1) + `,`, + `}`, + }, "") + return s +} +func (this *LabelPair) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LabelPair{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *Chunk) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Chunk{`, + `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `}`, + }, "") + return s +} +func (this *TransferChunksResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TransferChunksResponse{`, + `}`, + }, "") + return s +} +func (this *TailersCountRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TailersCountRequest{`, + `}`, + }, "") + return s +} +func (this *TailersCountResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&TailersCountResponse{`, + `Count:` + fmt.Sprintf("%v", this.Count) + `,`, + `}`, + }, "") + return s +} +func (this *GetChunkIDsRequest) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GetChunkIDsRequest{`, + `Matchers:` + fmt.Sprintf("%v", this.Matchers) + `,`, + `Start:` + strings.Replace(strings.Replace(this.Start.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `End:` + strings.Replace(strings.Replace(this.End.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *GetChunkIDsResponse) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GetChunkIDsResponse{`, + `ChunkIDs:` + fmt.Sprintf("%v", this.ChunkIDs) + `,`, + `}`, + }, "") + return s +} +func valueToStringLogproto(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *PushRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PushRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PushRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Streams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Streams = append(m.Streams, Stream{}) + if err := m.Streams[len(m.Streams)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PushResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PushResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PushResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.End, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Direction", wireType) + } + m.Direction = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Direction |= Direction(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shards", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shards = append(m.Shards, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SampleQueryRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SampleQueryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SampleQueryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.End, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shards", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shards = append(m.Shards, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SampleQueryResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SampleQueryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SampleQueryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Series", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Series = append(m.Series, Series{}) + if err := m.Series[len(m.Series)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Streams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Streams = append(m.Streams, Stream{}) + if err := m.Streams[len(m.Streams)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LabelRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LabelRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LabelRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Values = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Start == nil { + m.Start = new(time.Time) + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.End == nil { + m.End = new(time.Time) + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.End, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LabelResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LabelResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LabelResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Values = append(m.Values, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StreamAdapter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StreamAdapter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StreamAdapter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, EntryAdapter{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EntryAdapter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EntryAdapter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EntryAdapter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Line", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Line = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Sample) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Sample: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Sample: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.Value = float64(math.Float64frombits(v)) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + m.Hash = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Hash |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Series) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Series: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Series: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Samples", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Samples = append(m.Samples, Sample{}) + if err := m.Samples[len(m.Samples)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TailRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TailRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TailRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DelayFor", wireType) + } + m.DelayFor = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DelayFor |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TailResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TailResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TailResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Stream", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Stream == nil { + m.Stream = &Stream{} + } + if err := m.Stream.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DroppedStreams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DroppedStreams = append(m.DroppedStreams, &DroppedStream{}) + if err := m.DroppedStreams[len(m.DroppedStreams)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SeriesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SeriesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SeriesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.End, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Groups = append(m.Groups, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SeriesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SeriesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SeriesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Series", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Series = append(m.Series, SeriesIdentifier{}) + if err := m.Series[len(m.Series)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SeriesIdentifier) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SeriesIdentifier: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SeriesIdentifier: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Labels == nil { + m.Labels = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthLogproto + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthLogproto + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthLogproto + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthLogproto + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Labels[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DroppedStream) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DroppedStream: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DroppedStream: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.From, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.To, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TimeSeriesChunk) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TimeSeriesChunk: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TimeSeriesChunk: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromIngesterId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromIngesterId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = append(m.Labels, &LabelPair{}) + if err := m.Labels[len(m.Labels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chunks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Chunks = append(m.Chunks, &Chunk{}) + if err := m.Chunks[len(m.Chunks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LabelPair) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LabelPair: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LabelPair: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Chunk) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Chunk: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Chunk: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TransferChunksResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TransferChunksResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TransferChunksResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TailersCountRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TailersCountRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TailersCountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TailersCountResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TailersCountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TailersCountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetChunkIDsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetChunkIDsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetChunkIDsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Matchers", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Matchers = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Start, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.End, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetChunkIDsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetChunkIDsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetChunkIDsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChunkIDs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChunkIDs = append(m.ChunkIDs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipLogproto(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLogproto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLogproto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLogproto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthLogproto + } + iNdEx += length + if iNdEx < 0 { + return 0, ErrInvalidLengthLogproto + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLogproto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipLogproto(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + if iNdEx < 0 { + return 0, ErrInvalidLengthLogproto + } + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthLogproto = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowLogproto = fmt.Errorf("proto: integer overflow") +) diff --git a/pkg/logproto/logproto.proto b/pkg/logproto/logproto.proto new file mode 100644 index 0000000..ab20ad6 --- /dev/null +++ b/pkg/logproto/logproto.proto @@ -0,0 +1,166 @@ +syntax = "proto3"; + +package logproto; + +option go_package = "github.com/lixh00/loki-client-go/pkg/logproto"; + +import "google/protobuf/timestamp.proto"; +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +service Pusher { + rpc Push(PushRequest) returns (PushResponse) {}; +} + +service Querier { + rpc Query(QueryRequest) returns (stream QueryResponse) {}; + rpc QuerySample(SampleQueryRequest) returns (stream SampleQueryResponse) {}; + rpc Label(LabelRequest) returns (LabelResponse) {}; + rpc Tail(TailRequest) returns (stream TailResponse) {}; + rpc Series(SeriesRequest) returns (SeriesResponse) {}; + rpc TailersCount(TailersCountRequest) returns (TailersCountResponse) {}; + rpc GetChunkIDs(GetChunkIDsRequest) returns (GetChunkIDsResponse) {}; // GetChunkIDs returns ChunkIDs from the index store holding logs for given selectors and time-range. +} + +service Ingester { + rpc TransferChunks(stream TimeSeriesChunk) returns (TransferChunksResponse) {}; +} + +message PushRequest { + repeated StreamAdapter streams = 1 [(gogoproto.jsontag) = "streams", (gogoproto.customtype) = "Stream"]; +} + +message PushResponse { +} + +message QueryRequest { + string selector = 1; + uint32 limit = 2; + google.protobuf.Timestamp start = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp end = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + Direction direction = 5; + reserved 6; + repeated string shards = 7 [(gogoproto.jsontag) = "shards,omitempty"]; +} + +message SampleQueryRequest { + string selector = 1; + google.protobuf.Timestamp start = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp end = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + repeated string shards = 4 [(gogoproto.jsontag) = "shards,omitempty"]; +} + +message SampleQueryResponse { + repeated Series series = 1 [(gogoproto.customtype) = "Series", (gogoproto.nullable) = true]; +} + +enum Direction { + FORWARD = 0; + BACKWARD = 1; +} + +message QueryResponse { + repeated StreamAdapter streams = 1 [(gogoproto.customtype) = "Stream", (gogoproto.nullable) = true]; +} + +message LabelRequest { + string name = 1; + bool values = 2; // True to fetch label values, false for fetch labels names. + google.protobuf.Timestamp start = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = true]; + google.protobuf.Timestamp end = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = true]; +} + +message LabelResponse { + repeated string values = 1; +} + +message StreamAdapter { + string labels = 1 [(gogoproto.jsontag) = "labels"]; + repeated EntryAdapter entries = 2 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "entries"]; +} + +message EntryAdapter { + google.protobuf.Timestamp timestamp = 1 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.jsontag) = "ts"]; + string line = 2 [(gogoproto.jsontag) = "line"]; +} + +message Sample { + int64 timestamp = 1 [(gogoproto.jsontag) = "ts"]; + double value = 2 [(gogoproto.jsontag) = "value"]; + uint64 hash = 3 [(gogoproto.jsontag) = "hash"]; +} + +message Series { + string labels = 1 [(gogoproto.jsontag) = "labels"]; + repeated Sample samples = 2 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "samples"]; +} + +message TailRequest { + string query = 1; + reserved 2; + uint32 delayFor = 3; + uint32 limit = 4; + google.protobuf.Timestamp start = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +message TailResponse { + StreamAdapter stream = 1 [(gogoproto.customtype) = "Stream"]; + repeated DroppedStream droppedStreams = 2; +} + +message SeriesRequest { + google.protobuf.Timestamp start = 1 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp end = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + repeated string groups = 3; +} + +message SeriesResponse { + repeated SeriesIdentifier series = 1 [(gogoproto.nullable) = false]; +} + +message SeriesIdentifier { + map labels = 1; +} + +message DroppedStream { + google.protobuf.Timestamp from = 1 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp to = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + string labels = 3; +} + +message TimeSeriesChunk { + string from_ingester_id = 1; + string user_id = 2; + repeated LabelPair labels = 3; + repeated Chunk chunks = 4; +} + +message LabelPair { + string name = 1; + string value = 2; +} + +message Chunk { + bytes data = 1; +} + +message TransferChunksResponse { + +} + +message TailersCountRequest { + +} + +message TailersCountResponse { + uint32 count = 1; +} + +message GetChunkIDsRequest { + string matchers = 1; + google.protobuf.Timestamp start = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + google.protobuf.Timestamp end = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +message GetChunkIDsResponse { + repeated string chunkIDs = 1; +} \ No newline at end of file diff --git a/pkg/logproto/timestamp.go b/pkg/logproto/timestamp.go new file mode 100644 index 0000000..f2fb323 --- /dev/null +++ b/pkg/logproto/timestamp.go @@ -0,0 +1,106 @@ +package logproto + +import ( + "errors" + strconv "strconv" + time "time" + + "github.com/gogo/protobuf/types" +) + +const ( + // Seconds field of the earliest valid Timestamp. + // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + minValidSeconds = -62135596800 + // Seconds field just after the latest valid Timestamp. + // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + maxValidSeconds = 253402300800 +) + +// validateTimestamp determines whether a Timestamp is valid. +// A valid timestamp represents a time in the range +// [0001-01-01, 10000-01-01) and has a Nanos field +// in the range [0, 1e9). +// +// If the Timestamp is valid, validateTimestamp returns nil. +// Otherwise, it returns an error that describes +// the problem. +// +// Every valid Timestamp can be represented by a time.Time, but the converse is not true. +func validateTimestamp(ts *types.Timestamp) error { + if ts == nil { + return errors.New("timestamp: nil Timestamp") + } + if ts.Seconds < minValidSeconds { + return errors.New("timestamp: " + formatTimestamp(ts) + " before 0001-01-01") + } + if ts.Seconds >= maxValidSeconds { + return errors.New("timestamp: " + formatTimestamp(ts) + " after 10000-01-01") + } + if ts.Nanos < 0 || ts.Nanos >= 1e9 { + return errors.New("timestamp: " + formatTimestamp(ts) + ": nanos not in range [0, 1e9)") + } + return nil +} + +// formatTimestamp is equivalent to fmt.Sprintf("%#v", ts) +// but avoids the escape incurred by using fmt.Sprintf, eliminating +// unnecessary heap allocations. +func formatTimestamp(ts *types.Timestamp) string { + if ts == nil { + return "nil" + } + + seconds := strconv.FormatInt(ts.Seconds, 10) + nanos := strconv.FormatInt(int64(ts.Nanos), 10) + return "&types.Timestamp{Seconds: " + seconds + ",\nNanos: " + nanos + ",\n}" +} + +func SizeOfStdTime(t time.Time) int { + ts, err := timestampProto(t) + if err != nil { + return 0 + } + return ts.Size() +} + +func StdTimeMarshalTo(t time.Time, data []byte) (int, error) { + ts, err := timestampProto(t) + if err != nil { + return 0, err + } + return ts.MarshalTo(data) +} + +func StdTimeUnmarshal(t *time.Time, data []byte) error { + ts := &types.Timestamp{} + if err := ts.Unmarshal(data); err != nil { + return err + } + tt, err := timestampFromProto(ts) + if err != nil { + return err + } + *t = tt + return nil +} + +func timestampFromProto(ts *types.Timestamp) (time.Time, error) { + // Don't return the zero value on error, because corresponds to a valid + // timestamp. Instead return whatever time.Unix gives us. + var t time.Time + if ts == nil { + t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp + } else { + t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() + } + return t, validateTimestamp(ts) +} + +func timestampProto(t time.Time) (types.Timestamp, error) { + ts := types.Timestamp{ + Seconds: t.Unix(), + Nanos: int32(t.Nanosecond()), + } + return ts, validateTimestamp(&ts) +} diff --git a/pkg/logproto/types.go b/pkg/logproto/types.go new file mode 100644 index 0000000..f2a2ac0 --- /dev/null +++ b/pkg/logproto/types.go @@ -0,0 +1,475 @@ +package logproto + +import ( + "fmt" + "io" + "time" + + jsoniter "github.com/json-iterator/go" + "github.com/prometheus/prometheus/promql/parser" +) + +// Stream contains a unique labels set as a string and a set of entries for it. +// We are not using the proto generated version but this custom one so that we +// can improve serialization see benchmark. +type Stream struct { + Labels string `protobuf:"bytes,1,opt,name=labels,proto3" json:"labels"` + Entries []Entry `protobuf:"bytes,2,rep,name=entries,proto3,customtype=EntryAdapter" json:"entries"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (r *PushRequest) MarshalJSON() ([]byte, error) { + stream := jsoniter.ConfigDefault.BorrowStream(nil) + defer jsoniter.ConfigDefault.ReturnStream(stream) + + stream.WriteObjectStart() + stream.WriteObjectField("streams") + stream.WriteArrayStart() + for i, s := range r.Streams { + stream.WriteObjectStart() + stream.WriteObjectField("stream") + stream.WriteObjectStart() + lbs, err := parser.ParseMetric(s.Labels) + if err != nil { + continue + } + for i, lb := range lbs { + stream.WriteObjectField(lb.Name) + stream.WriteStringWithHTMLEscaped(lb.Value) + if i != len(lbs)-1 { + stream.WriteMore() + } + } + stream.WriteObjectEnd() + stream.WriteMore() + stream.WriteObjectField("values") + stream.WriteArrayStart() + for i, entry := range s.Entries { + stream.WriteArrayStart() + stream.WriteRaw(fmt.Sprintf(`"%d"`, entry.Timestamp.UnixNano())) + stream.WriteMore() + stream.WriteStringWithHTMLEscaped(entry.Line) + stream.WriteArrayEnd() + if i != len(s.Entries)-1 { + stream.WriteMore() + } + } + stream.WriteArrayEnd() + stream.WriteObjectEnd() + if i != len(r.Streams)-1 { + stream.WriteMore() + } + } + stream.WriteArrayEnd() + stream.WriteObjectEnd() + + return stream.Buffer(), nil +} + +// Entry is a log entry with a timestamp. +type Entry struct { + Timestamp time.Time `protobuf:"bytes,1,opt,name=timestamp,proto3,stdtime" json:"ts"` + Line string `protobuf:"bytes,2,opt,name=line,proto3" json:"line"` +} + +func (m *Stream) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Stream) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Labels) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Labels))) + i += copy(dAtA[i:], m.Labels) + } + if len(m.Entries) > 0 { + for _, msg := range m.Entries { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *Entry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Entry) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintLogproto(dAtA, i, uint64(SizeOfStdTime(m.Timestamp))) + n5, err := StdTimeMarshalTo(m.Timestamp, dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + if len(m.Line) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintLogproto(dAtA, i, uint64(len(m.Line))) + i += copy(dAtA[i:], m.Line) + } + return i, nil +} + +func (m *Stream) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Stream: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Stream: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, Entry{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *Entry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Entry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Line", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogproto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogproto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogproto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Line = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogproto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthLogproto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func (m *Stream) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Labels) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovLogproto(uint64(l)) + } + } + return n +} + +func (m *Entry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = SizeOfStdTime(m.Timestamp) + n += 1 + l + sovLogproto(uint64(l)) + l = len(m.Line) + if l > 0 { + n += 1 + l + sovLogproto(uint64(l)) + } + return n +} + +func (m *Stream) Equal(that interface{}) bool { + if that == nil { + return m == nil + } + + that1, ok := that.(*Stream) + if !ok { + that2, ok := that.(Stream) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return m == nil + } else if m == nil { + return false + } + if m.Labels != that1.Labels { + return false + } + if len(m.Entries) != len(that1.Entries) { + return false + } + for i := range m.Entries { + if !m.Entries[i].Equal(that1.Entries[i]) { + return false + } + } + return true +} + +func (m *Entry) Equal(that interface{}) bool { + if that == nil { + return m == nil + } + + that1, ok := that.(*Entry) + if !ok { + that2, ok := that.(Entry) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return m == nil + } else if m == nil { + return false + } + if !m.Timestamp.Equal(that1.Timestamp) { + return false + } + if m.Line != that1.Line { + return false + } + return true +} diff --git a/pkg/logproto/types_test.go b/pkg/logproto/types_test.go new file mode 100644 index 0000000..97517ce --- /dev/null +++ b/pkg/logproto/types_test.go @@ -0,0 +1,111 @@ +package logproto + +import ( + "testing" + time "time" + + "github.com/stretchr/testify/require" +) + +var ( + now = time.Now().UTC() + line = `level=info ts=2019-12-12T15:00:08.325Z caller=compact.go:441 component=tsdb msg="compact blocks" count=3 mint=1576130400000 maxt=1576152000000 ulid=01DVX9ZHNM71GRCJS7M34Q0EV7 sources="[01DVWNC6NWY1A60AZV3Z6DGS65 01DVWW7XXX75GHA6ZDTD170CSZ 01DVX33N5W86CWJJVRPAVXJRWJ]" duration=2.897213221s` + stream = Stream{ + Labels: `{job="foobar", cluster="foo-central1", namespace="bar", container_name="buzz"}`, + Entries: []Entry{ + {now, line}, + {now.Add(1 * time.Second), line}, + {now.Add(2 * time.Second), line}, + {now.Add(3 * time.Second), line}, + }, + } + streamAdapter = StreamAdapter{ + Labels: `{job="foobar", cluster="foo-central1", namespace="bar", container_name="buzz"}`, + Entries: []EntryAdapter{ + {now, line}, + {now.Add(1 * time.Second), line}, + {now.Add(2 * time.Second), line}, + {now.Add(3 * time.Second), line}, + }, + } +) + +func TestStream(t *testing.T) { + avg := testing.AllocsPerRun(200, func() { + b, err := stream.Marshal() + require.NoError(t, err) + + var new Stream + err = new.Unmarshal(b) + require.NoError(t, err) + + require.Equal(t, stream, new) + }) + t.Log("avg allocs per run:", avg) +} + +func TestStreamAdapter(t *testing.T) { + avg := testing.AllocsPerRun(200, func() { + b, err := streamAdapter.Marshal() + require.NoError(t, err) + + var new StreamAdapter + err = new.Unmarshal(b) + require.NoError(t, err) + + require.Equal(t, streamAdapter, new) + }) + t.Log("avg allocs per run:", avg) +} + +func TestCompatibility(t *testing.T) { + b, err := stream.Marshal() + require.NoError(t, err) + + var adapter StreamAdapter + err = adapter.Unmarshal(b) + require.NoError(t, err) + require.Equal(t, streamAdapter, adapter) + + ba, err := adapter.Marshal() + require.NoError(t, err) + require.Equal(t, b, ba) + + var new Stream + err = new.Unmarshal(ba) + require.NoError(t, err) + + require.Equal(t, stream, new) +} + +func BenchmarkStream(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + by, err := stream.Marshal() + if err != nil { + b.Fatal(err) + } + var new Stream + err = new.Unmarshal(by) + if err != nil { + b.Fatal(err) + } + } + +} + +func BenchmarkStreamAdapter(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + by, err := streamAdapter.Marshal() + if err != nil { + b.Fatal(err) + } + var new StreamAdapter + err = new.Unmarshal(by) + if err != nil { + b.Fatal(err) + } + } + +} diff --git a/pkg/metric/counters.go b/pkg/metric/counters.go new file mode 100644 index 0000000..bfab117 --- /dev/null +++ b/pkg/metric/counters.go @@ -0,0 +1,117 @@ +package metric + +import ( + "strings" + "time" + + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" +) + +const ( + CounterInc = "inc" + CounterAdd = "add" + + ErrCounterActionRequired = "counter action must be defined as either `inc` or `add`" + ErrCounterInvalidAction = "action %s is not valid, action must be either `inc` or `add`" + ErrCounterInvalidMatchAll = "`match_all: true` cannot be combined with `value`, please remove `match_all` or `value`" + ErrCounterInvalidCountBytes = "`count_entry_bytes: true` can only be set with `match_all: true`" + ErrCounterInvalidCountBytesAction = "`count_entry_bytes: true` can only be used with `action: add`" +) + +type CounterConfig struct { + MatchAll *bool `mapstructure:"match_all"` + CountBytes *bool `mapstructure:"count_entry_bytes"` + Value *string `mapstructure:"value"` + Action string `mapstructure:"action"` +} + +func validateCounterConfig(config *CounterConfig) error { + if config.Action == "" { + return errors.New(ErrCounterActionRequired) + } + config.Action = strings.ToLower(config.Action) + if config.Action != CounterInc && config.Action != CounterAdd { + return errors.Errorf(ErrCounterInvalidAction, config.Action) + } + if config.MatchAll != nil && *config.MatchAll && config.Value != nil { + return errors.Errorf(ErrCounterInvalidMatchAll) + } + if config.CountBytes != nil && *config.CountBytes && (config.MatchAll == nil || !*config.MatchAll) { + return errors.New(ErrCounterInvalidCountBytes) + } + if config.CountBytes != nil && *config.CountBytes && config.Action != CounterAdd { + return errors.New(ErrCounterInvalidCountBytesAction) + } + return nil +} + +func parseCounterConfig(config interface{}) (*CounterConfig, error) { + cfg := &CounterConfig{} + err := mapstructure.Decode(config, cfg) + if err != nil { + return nil, err + } + return cfg, nil +} + +// Counters is a vec tor of counters for a each log stream. +type Counters struct { + *metricVec + Cfg *CounterConfig +} + +// NewCounters creates a new counter vec. +func NewCounters(name, help string, config interface{}, maxIdleSec int64) (*Counters, error) { + cfg, err := parseCounterConfig(config) + if err != nil { + return nil, err + } + err = validateCounterConfig(cfg) + if err != nil { + return nil, err + } + return &Counters{ + metricVec: newMetricVec(func(labels map[string]string) prometheus.Metric { + return &expiringCounter{prometheus.NewCounter(prometheus.CounterOpts{ + Help: help, + Name: name, + ConstLabels: labels, + }), + 0, + } + }, maxIdleSec), + Cfg: cfg, + }, nil +} + +// With returns the counter associated with a stream labelset. +func (c *Counters) With(labels model.LabelSet) prometheus.Counter { + return c.metricVec.With(labels).(prometheus.Counter) +} + +type expiringCounter struct { + prometheus.Counter + lastModSec int64 +} + +// Inc increments the counter by 1. Use Add to increment it by arbitrary +// non-negative values. +func (e *expiringCounter) Inc() { + e.Counter.Inc() + e.lastModSec = time.Now().Unix() +} + +// Add adds the given value to the counter. It panics if the value is < +// 0. +func (e *expiringCounter) Add(val float64) { + e.Counter.Add(val) + e.lastModSec = time.Now().Unix() +} + +// HasExpired implements Expirable +func (e *expiringCounter) HasExpired(currentTimeSec int64, maxAgeSec int64) bool { + return currentTimeSec-e.lastModSec >= maxAgeSec +} diff --git a/pkg/metric/counters_test.go b/pkg/metric/counters_test.go new file mode 100644 index 0000000..49b3873 --- /dev/null +++ b/pkg/metric/counters_test.go @@ -0,0 +1,140 @@ +package metric + +import ( + "testing" + "time" + + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" + "github.com/stretchr/testify/assert" +) + +var ( + counterTestTrue = true + counterTestFalse = false + counterTestVal = "some val" +) + +func Test_validateCounterConfig(t *testing.T) { + t.Parallel() + tests := []struct { + name string + config CounterConfig + err error + }{ + {"invalid action", + CounterConfig{ + Action: "del", + }, + errors.Errorf(ErrCounterInvalidAction, "del"), + }, + {"invalid counter match all", + CounterConfig{ + MatchAll: &counterTestTrue, + Value: &counterTestVal, + Action: "inc", + }, + errors.New(ErrCounterInvalidMatchAll), + }, + {"invalid counter match bytes", + CounterConfig{ + MatchAll: nil, + CountBytes: &counterTestTrue, + Action: "add", + }, + errors.New(ErrCounterInvalidCountBytes), + }, + {"invalid counter match bytes action", + CounterConfig{ + MatchAll: &counterTestTrue, + CountBytes: &counterTestTrue, + Action: "inc", + }, + errors.New(ErrCounterInvalidCountBytesAction), + }, + {"valid counter match bytes", + CounterConfig{ + MatchAll: &counterTestTrue, + CountBytes: &counterTestTrue, + Action: "add", + }, + nil, + }, + {"valid", + CounterConfig{ + Value: &counterTestVal, + Action: "inc", + }, + nil, + }, + {"valid match all is false", + CounterConfig{ + MatchAll: &counterTestFalse, + Value: &counterTestVal, + Action: "inc", + }, + nil, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + err := validateCounterConfig(&tt.config) + if ((err != nil) && (err.Error() != tt.err.Error())) || (err == nil && tt.err != nil) { + t.Errorf("Metrics stage validation error, expected error = %v, actual error = %v", tt.err, err) + return + } + }) + } +} + +func TestCounterExpiration(t *testing.T) { + t.Parallel() + cfg := CounterConfig{ + Action: "inc", + } + + cnt, err := NewCounters("test1", "HELP ME!!!!!", cfg, 1) + assert.Nil(t, err) + + // Create a label and increment the counter + lbl1 := model.LabelSet{} + lbl1["test"] = "i don't wanna make this a constant" + cnt.With(lbl1).Inc() + + // Collect the metrics, should still find the metric in the map + collect(cnt) + assert.Contains(t, cnt.metrics, lbl1.Fingerprint()) + + time.Sleep(1100 * time.Millisecond) // Wait just past our max idle of 1 sec + + //Add another counter with new label val + lbl2 := model.LabelSet{} + lbl2["test"] = "eat this linter" + cnt.With(lbl2).Inc() + + // Collect the metrics, first counter should have expired and removed, second should still be present + collect(cnt) + assert.NotContains(t, cnt.metrics, lbl1.Fingerprint()) + assert.Contains(t, cnt.metrics, lbl2.Fingerprint()) +} + +func collect(c prometheus.Collector) { + done := make(chan struct{}) + collector := make(chan prometheus.Metric) + + go func() { + defer close(done) + c.Collect(collector) + }() + + for { + select { + case <-collector: + case <-done: + return + } + } +} diff --git a/pkg/metric/gauges.go b/pkg/metric/gauges.go new file mode 100644 index 0000000..2b5b8b8 --- /dev/null +++ b/pkg/metric/gauges.go @@ -0,0 +1,136 @@ +package metric + +import ( + "strings" + "time" + + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" +) + +const ( + GaugeSet = "set" + GaugeInc = "inc" + GaugeDec = "dec" + GaugeAdd = "add" + GaugeSub = "sub" + + ErrGaugeActionRequired = "gauge action must be defined as `set`, `inc`, `dec`, `add`, or `sub`" + ErrGaugeInvalidAction = "action %s is not valid, action must be `set`, `inc`, `dec`, `add`, or `sub`" +) + +type GaugeConfig struct { + Value *string `mapstructure:"value"` + Action string `mapstructure:"action"` +} + +func validateGaugeConfig(config *GaugeConfig) error { + if config.Action == "" { + return errors.New(ErrGaugeActionRequired) + } + config.Action = strings.ToLower(config.Action) + if config.Action != GaugeSet && + config.Action != GaugeInc && + config.Action != GaugeDec && + config.Action != GaugeAdd && + config.Action != GaugeSub { + return errors.Errorf(ErrGaugeInvalidAction, config.Action) + } + return nil +} + +func parseGaugeConfig(config interface{}) (*GaugeConfig, error) { + cfg := &GaugeConfig{} + err := mapstructure.Decode(config, cfg) + if err != nil { + return nil, err + } + return cfg, nil +} + +// Gauges is a vector of gauges for a each log stream. +type Gauges struct { + *metricVec + Cfg *GaugeConfig +} + +// NewGauges creates a new gauge vec. +func NewGauges(name, help string, config interface{}, maxIdleSec int64) (*Gauges, error) { + cfg, err := parseGaugeConfig(config) + if err != nil { + return nil, err + } + err = validateGaugeConfig(cfg) + if err != nil { + return nil, err + } + return &Gauges{ + metricVec: newMetricVec(func(labels map[string]string) prometheus.Metric { + return &expiringGauge{prometheus.NewGauge(prometheus.GaugeOpts{ + Help: help, + Name: name, + ConstLabels: labels, + }), + 0, + } + }, maxIdleSec), + Cfg: cfg, + }, nil +} + +// With returns the gauge associated with a stream labelset. +func (g *Gauges) With(labels model.LabelSet) prometheus.Gauge { + return g.metricVec.With(labels).(prometheus.Gauge) +} + +type expiringGauge struct { + prometheus.Gauge + lastModSec int64 +} + +// Set sets the Gauge to an arbitrary value. +func (g *expiringGauge) Set(val float64) { + g.Gauge.Set(val) + g.lastModSec = time.Now().Unix() +} + +// Inc increments the Gauge by 1. Use Add to increment it by arbitrary +// values. +func (g *expiringGauge) Inc() { + g.Gauge.Inc() + g.lastModSec = time.Now().Unix() +} + +// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary +// values. +func (g *expiringGauge) Dec() { + g.Gauge.Dec() + g.lastModSec = time.Now().Unix() +} + +// Add adds the given value to the Gauge. (The value can be negative, +// resulting in a decrease of the Gauge.) +func (g *expiringGauge) Add(val float64) { + g.Gauge.Add(val) + g.lastModSec = time.Now().Unix() +} + +// Sub subtracts the given value from the Gauge. (The value can be +// negative, resulting in an increase of the Gauge.) +func (g *expiringGauge) Sub(val float64) { + g.Gauge.Sub(val) + g.lastModSec = time.Now().Unix() +} + +// SetToCurrentTime sets the Gauge to the current Unix time in seconds. +func (g *expiringGauge) SetToCurrentTime() { + g.Gauge.SetToCurrentTime() + g.lastModSec = time.Now().Unix() +} + +// HasExpired implements Expirable +func (g *expiringGauge) HasExpired(currentTimeSec int64, maxAgeSec int64) bool { + return currentTimeSec-g.lastModSec >= maxAgeSec +} diff --git a/pkg/metric/gauges_test.go b/pkg/metric/gauges_test.go new file mode 100644 index 0000000..10eb172 --- /dev/null +++ b/pkg/metric/gauges_test.go @@ -0,0 +1,40 @@ +package metric + +import ( + "testing" + "time" + + "github.com/prometheus/common/model" + "github.com/stretchr/testify/assert" +) + +func TestGaugeExpiration(t *testing.T) { + t.Parallel() + cfg := GaugeConfig{ + Action: "inc", + } + + gag, err := NewGauges("test1", "HELP ME!!!!!", cfg, 1) + assert.Nil(t, err) + + // Create a label and increment the gauge + lbl1 := model.LabelSet{} + lbl1["test"] = "app" + gag.With(lbl1).Inc() + + // Collect the metrics, should still find the metric in the map + collect(gag) + assert.Contains(t, gag.metrics, lbl1.Fingerprint()) + + time.Sleep(1100 * time.Millisecond) // Wait just past our max idle of 1 sec + + //Add another gauge with new label val + lbl2 := model.LabelSet{} + lbl2["test"] = "app2" + gag.With(lbl2).Inc() + + // Collect the metrics, first gauge should have expired and removed, second should still be present + collect(gag) + assert.NotContains(t, gag.metrics, lbl1.Fingerprint()) + assert.Contains(t, gag.metrics, lbl2.Fingerprint()) +} diff --git a/pkg/metric/histograms.go b/pkg/metric/histograms.go new file mode 100644 index 0000000..c920e0a --- /dev/null +++ b/pkg/metric/histograms.go @@ -0,0 +1,79 @@ +package metric + +import ( + "time" + + "github.com/mitchellh/mapstructure" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" +) + +type HistogramConfig struct { + Value *string `mapstructure:"value"` + Buckets []float64 `mapstructure:"buckets"` +} + +func validateHistogramConfig(config *HistogramConfig) error { + return nil +} + +func parseHistogramConfig(config interface{}) (*HistogramConfig, error) { + cfg := &HistogramConfig{} + err := mapstructure.Decode(config, cfg) + if err != nil { + return nil, err + } + return cfg, nil +} + +// Histograms is a vector of histograms for a each log stream. +type Histograms struct { + *metricVec + Cfg *HistogramConfig +} + +// NewHistograms creates a new histogram vec. +func NewHistograms(name, help string, config interface{}, maxIdleSec int64) (*Histograms, error) { + cfg, err := parseHistogramConfig(config) + if err != nil { + return nil, err + } + err = validateHistogramConfig(cfg) + if err != nil { + return nil, err + } + return &Histograms{ + metricVec: newMetricVec(func(labels map[string]string) prometheus.Metric { + return &expiringHistogram{prometheus.NewHistogram(prometheus.HistogramOpts{ + Help: help, + Name: name, + ConstLabels: labels, + Buckets: cfg.Buckets, + }), + 0, + } + }, maxIdleSec), + Cfg: cfg, + }, nil +} + +// With returns the histogram associated with a stream labelset. +func (h *Histograms) With(labels model.LabelSet) prometheus.Histogram { + return h.metricVec.With(labels).(prometheus.Histogram) +} + +type expiringHistogram struct { + prometheus.Histogram + lastModSec int64 +} + +// Observe adds a single observation to the histogram. +func (h *expiringHistogram) Observe(val float64) { + h.Histogram.Observe(val) + h.lastModSec = time.Now().Unix() +} + +// HasExpired implements Expirable +func (h *expiringHistogram) HasExpired(currentTimeSec int64, maxAgeSec int64) bool { + return currentTimeSec-h.lastModSec >= maxAgeSec +} diff --git a/pkg/metric/histograms_test.go b/pkg/metric/histograms_test.go new file mode 100644 index 0000000..ffb18cd --- /dev/null +++ b/pkg/metric/histograms_test.go @@ -0,0 +1,38 @@ +package metric + +import ( + "testing" + "time" + + "github.com/prometheus/common/model" + "github.com/stretchr/testify/assert" +) + +func TestHistogramExpiration(t *testing.T) { + t.Parallel() + cfg := HistogramConfig{} + + hist, err := NewHistograms("test1", "HELP ME!!!!!", cfg, 1) + assert.Nil(t, err) + + // Create a label and increment the histogram + lbl1 := model.LabelSet{} + lbl1["test"] = "app" + hist.With(lbl1).Observe(23) + + // Collect the metrics, should still find the metric in the map + collect(hist) + assert.Contains(t, hist.metrics, lbl1.Fingerprint()) + + time.Sleep(1100 * time.Millisecond) // Wait just past our max idle of 1 sec + + //Add another histogram with new label val + lbl2 := model.LabelSet{} + lbl2["test"] = "app2" + hist.With(lbl2).Observe(2) + + // Collect the metrics, first histogram should have expired and removed, second should still be present + collect(hist) + assert.NotContains(t, hist.metrics, lbl1.Fingerprint()) + assert.Contains(t, hist.metrics, lbl2.Fingerprint()) +} diff --git a/pkg/metric/metricvec.go b/pkg/metric/metricvec.go new file mode 100644 index 0000000..0af361f --- /dev/null +++ b/pkg/metric/metricvec.go @@ -0,0 +1,82 @@ +package metric + +import ( + "sync" + "time" + + "github.com/lixh00/loki-client-go/pkg/labelutil" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" +) + +// Expirable allows checking if something has exceeded the provided maxAge based on the provided currentTime +type Expirable interface { + HasExpired(currentTimeSec int64, maxAgeSec int64) bool +} + +type metricVec struct { + factory func(labels map[string]string) prometheus.Metric + mtx sync.Mutex + metrics map[model.Fingerprint]prometheus.Metric + maxAgeSec int64 +} + +func newMetricVec(factory func(labels map[string]string) prometheus.Metric, maxAgeSec int64) *metricVec { + return &metricVec{ + metrics: map[model.Fingerprint]prometheus.Metric{}, + factory: factory, + maxAgeSec: maxAgeSec, + } +} + +// Describe implements prometheus.Collector and doesn't declare any metrics on purpose to bypass prometheus validation. +// see https://godoc.org/github.com/prometheus/client_golang/prometheus#hdr-Custom_Collectors_and_constant_Metrics search for "unchecked" +func (c *metricVec) Describe(ch chan<- *prometheus.Desc) {} + +// Collect implements prometheus.Collector +func (c *metricVec) Collect(ch chan<- prometheus.Metric) { + c.mtx.Lock() + defer c.mtx.Unlock() + for _, m := range c.metrics { + ch <- m + } + c.prune() +} + +// With returns the metric associated with the labelset. +func (c *metricVec) With(labels model.LabelSet) prometheus.Metric { + c.mtx.Lock() + defer c.mtx.Unlock() + fp := labels.Fingerprint() + var ok bool + var metric prometheus.Metric + if metric, ok = c.metrics[fp]; !ok { + metric = c.factory(labelutil.ModelLabelSetToMap(labels)) + c.metrics[fp] = metric + } + return metric +} + +func (c *metricVec) Delete(labels model.LabelSet) bool { + c.mtx.Lock() + defer c.mtx.Unlock() + fp := labels.Fingerprint() + _, ok := c.metrics[fp] + if ok { + delete(c.metrics, fp) + } + return ok +} + +// prune will remove all metrics which implement the Expirable interface and have expired +// it does not take out a lock on the metrics map so whoever calls this function should do so. +func (c *metricVec) prune() { + currentTimeSec := time.Now().Unix() + for fp, m := range c.metrics { + if em, ok := m.(Expirable); ok { + if em.HasExpired(currentTimeSec, c.maxAgeSec) { + delete(c.metrics, fp) + } + } + } +} diff --git a/pkg/urlutil/url.go b/pkg/urlutil/url.go new file mode 100644 index 0000000..a403f00 --- /dev/null +++ b/pkg/urlutil/url.go @@ -0,0 +1,59 @@ +package urlutil + +import "net/url" + +// URLValue is a url.URL that can be used as a flag. +type URLValue struct { + *url.URL +} + +// String implements flag.Value +func (v URLValue) String() string { + if v.URL == nil { + return "" + } + return v.URL.String() +} + +// Set implements flag.Value +func (v *URLValue) Set(s string) error { + u, err := url.Parse(s) + if err != nil { + return err + } + v.URL = u + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (v *URLValue) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + + // An empty string means no URL has been configured. + if s == "" { + v.URL = nil + return nil + } + + return v.Set(s) +} + +// MarshalYAML implements yaml.Marshaler. +func (v URLValue) MarshalYAML() (interface{}, error) { + if v.URL == nil { + return "", nil + } + + // Mask out passwords when marshalling URLs back to YAML. + u := *v.URL + if u.User != nil { + if _, set := u.User.Password(); set { + u.User = url.UserPassword(u.User.Username(), "********") + } + } + + return u.String(), nil +}