Skip to content

Commit 3619a77

Browse files
c24tandrewsg
authored andcommitted
Add OpenCensus metrics quickstart (GoogleCloudPlatform#2079)
* Add opencensus python metrics quickstart * Change loop var name * Update for new_stats_exporter API change * Add README, requirements files * Add OC metrics quickstart tests * Make example executable * Add 5s grace period for export * Print project ID to stdout on exporter creation * s/bash/sh in README
1 parent 9396eb5 commit 3619a77

File tree

4 files changed

+194
-0
lines changed

4 files changed

+194
-0
lines changed

opencensus/README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<img src="https://avatars2.githubusercontent.com/u/38480854?v=3&s=96" alt="OpenCensus logo" title="OpenCensus" align="right" height="96" width="96"/>
2+
3+
# OpenCensus Stackdriver Metrics Sample
4+
5+
[OpenCensus](https://opencensus.io) is a toolkit for collecting application
6+
performance and behavior data. OpenCensus includes utilities for distributed
7+
tracing, metrics collection, and context propagation within and between
8+
services.
9+
10+
This example demonstrates using the OpenCensus client to send metrics data to
11+
the [Stackdriver Monitoring](https://cloud.google.com/monitoring/docs/)
12+
backend.
13+
14+
## Prerequisites
15+
16+
Install the OpenCensus core and Stackdriver exporter libraries:
17+
18+
```sh
19+
pip install -r opencensus/requirements.txt
20+
```
21+
22+
Make sure that your environment is configured to [authenticate with
23+
GCP](https://cloud.google.com/docs/authentication/getting-started).
24+
25+
## Running the example
26+
27+
```sh
28+
python opencensus/metrics_quickstart.py
29+
```
30+
31+
The example generates a histogram of simulated latencies, which is exported to
32+
Stackdriver after 60 seconds. After it's exported, the histogram will be
33+
visible on the [Stackdriver Metrics
34+
Explorer](https://app.google.stackdriver.com/metrics-explorer) page as
35+
`OpenCensus/task_latency_view`.

opencensus/metrics_quickstart.py

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2019 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# [START monitoring_opencensus_metrics_quickstart]
18+
19+
from random import random
20+
import time
21+
22+
from opencensus.ext.stackdriver import stats_exporter
23+
from opencensus.stats import aggregation
24+
from opencensus.stats import measure
25+
from opencensus.stats import stats
26+
from opencensus.stats import view
27+
28+
29+
# A measure that represents task latency in ms.
30+
LATENCY_MS = measure.MeasureFloat(
31+
"task_latency",
32+
"The task latency in milliseconds",
33+
"ms")
34+
35+
# A view of the task latency measure that aggregates measurements according to
36+
# a histogram with predefined bucket boundaries. This aggregate is periodically
37+
# exported to Stackdriver Monitoring.
38+
LATENCY_VIEW = view.View(
39+
"task_latency_distribution",
40+
"The distribution of the task latencies",
41+
[],
42+
LATENCY_MS,
43+
# Latency in buckets: [>=0ms, >=100ms, >=200ms, >=400ms, >=1s, >=2s, >=4s]
44+
aggregation.DistributionAggregation(
45+
[100.0, 200.0, 400.0, 1000.0, 2000.0, 4000.0]))
46+
47+
48+
def main():
49+
# Register the view. Measurements are only aggregated and exported if
50+
# they're associated with a registered view.
51+
stats.stats.view_manager.register_view(LATENCY_VIEW)
52+
53+
# Create the Stackdriver stats exporter and start exporting metrics in the
54+
# background, once every 60 seconds by default.
55+
exporter = stats_exporter.new_stats_exporter()
56+
print('Exporting stats to project "{}"'
57+
.format(exporter.options.project_id))
58+
59+
# Record 100 fake latency values between 0 and 5 seconds.
60+
for num in range(100):
61+
ms = random() * 5 * 1000
62+
print("Latency {}: {}".format(num, ms))
63+
64+
mmap = stats.stats.stats_recorder.new_measurement_map()
65+
mmap.measure_float_put(LATENCY_MS, ms)
66+
mmap.record()
67+
68+
# Keep the thread alive long enough for the exporter to export at least
69+
# once.
70+
time.sleep(65)
71+
72+
73+
if __name__ == '__main__':
74+
main()
75+
76+
# [END monitoring_opencensus_metrics_quickstart]

opencensus/metrics_quickstart_test.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright 2019 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from unittest import mock
16+
import unittest
17+
18+
from opencensus.ext.stackdriver import stats_exporter
19+
from opencensus.stats import aggregation
20+
from opencensus.stats import measure
21+
from opencensus.stats import stats
22+
from opencensus.stats import view
23+
24+
25+
class TestMetricsQuickstart(unittest.TestCase):
26+
"""Sanity checks for the OpenCensus metrics quickstart examples.
27+
28+
These tests check that a few basic features of the library work as expected
29+
in order for the demo to run. See the opencensus and
30+
opencensus-ext-stackdriver source for actual library tests.
31+
"""
32+
def test_measure_creation(self):
33+
measure.MeasureFloat(
34+
"task_latency",
35+
"The task latency in milliseconds",
36+
"ms")
37+
38+
def test_view_creation(self):
39+
test_view = view.View(
40+
"task_latency_distribution",
41+
"The distribution of the task latencies",
42+
[],
43+
mock.Mock(),
44+
aggregation.DistributionAggregation([1.0, 2.0, 3.0]))
45+
# Check that metric descriptor conversion doesn't crash
46+
test_view.get_metric_descriptor()
47+
48+
# Don't modify global stats
49+
@mock.patch('opencensus.ext.stackdriver.stats_exporter.stats.stats',
50+
stats._Stats())
51+
def test_measurement_map_record(self):
52+
mock_measure = mock.Mock()
53+
mock_measure_name = mock.Mock()
54+
mock_measure.name = mock_measure_name
55+
mock_view = mock.Mock()
56+
mock_view.columns = []
57+
mock_view.measure = mock_measure
58+
59+
stats.stats.view_manager.register_view(mock_view)
60+
61+
mmap = stats.stats.stats_recorder.new_measurement_map()
62+
mmap.measure_float_put(mock_measure, 1.0)
63+
mmap.record()
64+
65+
# Reaching into the stats internals here to check that recording the
66+
# measurement map affects view data.
67+
m2vd = (stats.stats.view_manager.measure_to_view_map
68+
._measure_to_view_data_list_map)
69+
self.assertIn(mock_measure_name, m2vd)
70+
[view_data] = m2vd[mock_measure_name]
71+
agg_data = view_data.tag_value_aggregation_data_map[tuple()]
72+
agg_data.add_sample.assert_called_once()
73+
74+
@mock.patch('opencensus.ext.stackdriver.stats_exporter'
75+
'.monitoring_v3.MetricServiceClient')
76+
def test_new_stats_exporter(self, mock_client):
77+
transport = stats_exporter.new_stats_exporter()
78+
self.assertIsNotNone(transport)
79+
self.assertIsNotNone(transport.options)
80+
self.assertIsNotNone(transport.options.project_id)

opencensus/requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
grpcio
2+
opencensus-ext-stackdriver==0.2.1
3+
opencensus==0.4.1

0 commit comments

Comments
 (0)