• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018, OpenCensus Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.opencensus.examples.quickstart;
18 
19 import io.opencensus.common.Scope;
20 import io.opencensus.exporter.stats.prometheus.PrometheusStatsCollector;
21 import io.opencensus.stats.Aggregation;
22 import io.opencensus.stats.Aggregation.Distribution;
23 import io.opencensus.stats.BucketBoundaries;
24 import io.opencensus.stats.Measure.MeasureDouble;
25 import io.opencensus.stats.Measure.MeasureLong;
26 import io.opencensus.stats.Stats;
27 import io.opencensus.stats.StatsRecorder;
28 import io.opencensus.stats.View;
29 import io.opencensus.stats.View.Name;
30 import io.opencensus.stats.ViewManager;
31 import io.opencensus.tags.TagContext;
32 import io.opencensus.tags.TagKey;
33 import io.opencensus.tags.TagValue;
34 import io.opencensus.tags.Tagger;
35 import io.opencensus.tags.Tags;
36 import io.prometheus.client.exporter.HTTPServer;
37 import java.io.BufferedReader;
38 import java.io.IOException;
39 import java.io.InputStreamReader;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collections;
43 import java.util.List;
44 
45 /** Sample application that shows how to record stats and export to Prometheus. */
46 public final class Repl {
47 
48   // The latency in milliseconds
49   private static final MeasureDouble M_LATENCY_MS =
50       MeasureDouble.create("repl/latency", "The latency in milliseconds per REPL loop", "ms");
51 
52   // Counts the number of lines read in from standard input.
53   private static final MeasureLong M_LINES_IN =
54       MeasureLong.create("repl/lines_in", "The number of lines read in", "1");
55 
56   // Counts the number of non EOF(end-of-file) errors.
57   private static final MeasureLong M_ERRORS =
58       MeasureLong.create("repl/errors", "The number of errors encountered", "1");
59 
60   // Counts/groups the lengths of lines read in.
61   private static final MeasureLong M_LINE_LENGTHS =
62       MeasureLong.create("repl/line_lengths", "The distribution of line lengths", "By");
63 
64   // The tag "method"
65   private static final TagKey KEY_METHOD = TagKey.create("method");
66 
67   private static final Tagger tagger = Tags.getTagger();
68   private static final StatsRecorder statsRecorder = Stats.getStatsRecorder();
69 
70   /** Main launcher for the Repl example. */
main(String... args)71   public static void main(String... args) {
72     // Step 1. Enable OpenCensus Metrics.
73     try {
74       setupOpenCensusAndPrometheusExporter();
75     } catch (IOException e) {
76       System.err.println("Failed to create and register OpenCensus Prometheus Stats exporter " + e);
77       return;
78     }
79 
80     BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
81 
82     while (true) {
83       try {
84         readEvaluateProcessLine(stdin);
85       } catch (IOException e) {
86         System.err.println("EOF bye " + e);
87         return;
88       } catch (Exception e) {
89         recordTaggedStat(KEY_METHOD, "repl", M_ERRORS, new Long(1));
90         return;
91       }
92     }
93   }
94 
recordStat(MeasureLong ml, Long n)95   private static void recordStat(MeasureLong ml, Long n) {
96     TagContext tctx = tagger.emptyBuilder().build();
97     try (Scope ss = tagger.withTagContext(tctx)) {
98       statsRecorder.newMeasureMap().put(ml, n).record();
99     }
100   }
101 
recordTaggedStat(TagKey key, String value, MeasureLong ml, Long n)102   private static void recordTaggedStat(TagKey key, String value, MeasureLong ml, Long n) {
103     TagContext tctx = tagger.emptyBuilder().put(key, TagValue.create(value)).build();
104     try (Scope ss = tagger.withTagContext(tctx)) {
105       statsRecorder.newMeasureMap().put(ml, n).record();
106     }
107   }
108 
recordTaggedStat(TagKey key, String value, MeasureDouble md, Double d)109   private static void recordTaggedStat(TagKey key, String value, MeasureDouble md, Double d) {
110     TagContext tctx = tagger.emptyBuilder().put(key, TagValue.create(value)).build();
111     try (Scope ss = tagger.withTagContext(tctx)) {
112       statsRecorder.newMeasureMap().put(md, d).record();
113     }
114   }
115 
processLine(String line)116   private static String processLine(String line) {
117     long startTimeNs = System.nanoTime();
118 
119     try {
120       return line.toUpperCase();
121     } catch (Exception e) {
122       recordTaggedStat(KEY_METHOD, "processLine", M_ERRORS, new Long(1));
123       return "";
124     } finally {
125       long totalTimeNs = System.nanoTime() - startTimeNs;
126       double timespentMs = (new Double(totalTimeNs)) / 1e6;
127       recordTaggedStat(KEY_METHOD, "processLine", M_LATENCY_MS, timespentMs);
128     }
129   }
130 
readEvaluateProcessLine(BufferedReader in)131   private static void readEvaluateProcessLine(BufferedReader in) throws IOException {
132     System.out.print("> ");
133     System.out.flush();
134 
135     String line = in.readLine();
136     String processed = processLine(line);
137     System.out.println("< " + processed + "\n");
138     if (line != null && line.length() > 0) {
139       recordStat(M_LINES_IN, new Long(1));
140       recordStat(M_LINE_LENGTHS, new Long(line.length()));
141     }
142   }
143 
registerAllViews()144   private static void registerAllViews() {
145     // Defining the distribution aggregations
146     Aggregation latencyDistribution =
147         Distribution.create(
148             BucketBoundaries.create(
149                 Arrays.asList(
150                     // [>=0ms, >=25ms, >=50ms, >=75ms, >=100ms, >=200ms, >=400ms, >=600ms, >=800ms,
151                     // >=1s, >=2s, >=4s, >=6s]
152                     0.0,
153                     25.0,
154                     50.0,
155                     75.0,
156                     100.0,
157                     200.0,
158                     400.0,
159                     600.0,
160                     800.0,
161                     1000.0,
162                     2000.0,
163                     4000.0,
164                     6000.0)));
165 
166     Aggregation lengthsDistribution =
167         Distribution.create(
168             BucketBoundaries.create(
169                 Arrays.asList(
170                     // [>=0B, >=5B, >=10B, >=20B, >=40B, >=60B, >=80B, >=100B, >=200B, >=400B,
171                     // >=600B,
172                     // >=800B, >=1000B]
173                     0.0,
174                     5.0,
175                     10.0,
176                     20.0,
177                     40.0,
178                     60.0,
179                     80.0,
180                     100.0,
181                     200.0,
182                     400.0,
183                     600.0,
184                     800.0,
185                     1000.0)));
186 
187     // Define the count aggregation
188     Aggregation countAggregation = Aggregation.Count.create();
189 
190     // So tagKeys
191     List<TagKey> noKeys = new ArrayList<TagKey>();
192 
193     // Define the views
194     View[] views =
195         new View[] {
196           View.create(
197               Name.create("ocjavametrics/latency"),
198               "The distribution of latencies",
199               M_LATENCY_MS,
200               latencyDistribution,
201               Collections.singletonList(KEY_METHOD)),
202           View.create(
203               Name.create("ocjavametrics/lines_in"),
204               "The number of lines read in from standard input",
205               M_LINES_IN,
206               countAggregation,
207               noKeys),
208           View.create(
209               Name.create("ocjavametrics/errors"),
210               "The number of errors encountered",
211               M_ERRORS,
212               countAggregation,
213               Collections.singletonList(KEY_METHOD)),
214           View.create(
215               Name.create("ocjavametrics/line_lengths"),
216               "The distribution of line lengths",
217               M_LINE_LENGTHS,
218               lengthsDistribution,
219               noKeys)
220         };
221 
222     // Create the view manager
223     ViewManager vmgr = Stats.getViewManager();
224 
225     // Then finally register the views
226     for (View view : views) {
227       vmgr.registerView(view);
228     }
229   }
230 
setupOpenCensusAndPrometheusExporter()231   private static void setupOpenCensusAndPrometheusExporter() throws IOException {
232     // Firstly register the views
233     registerAllViews();
234 
235     // Create and register the Prometheus exporter
236     PrometheusStatsCollector.createAndRegister();
237 
238     // Run the server as a daemon on address "localhost:8889"
239     HTTPServer server = new HTTPServer("localhost", 8889, true);
240   }
241 }
242