Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit 24893eb

Browse files
authored
Add HTTP example server. (#314)
1 parent edfa2a3 commit 24893eb

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed

examples/http/BUILD

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2019, OpenCensus Authors
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+
load("//opencensus:copts.bzl", "DEFAULT_COPTS", "TEST_COPTS")
16+
17+
licenses(["notice"]) # Apache License 2.0
18+
19+
package(default_visibility = ["//visibility:private"])
20+
21+
cc_binary(
22+
name = "server",
23+
srcs = ["server.cc"],
24+
copts = DEFAULT_COPTS,
25+
deps = [
26+
"//opencensus/exporters/stats/prometheus:prometheus_exporter",
27+
"//opencensus/exporters/stats/stackdriver:stackdriver_exporter",
28+
"//opencensus/exporters/stats/stdout:stdout_exporter",
29+
"//opencensus/exporters/trace/stackdriver:stackdriver_exporter",
30+
"//opencensus/exporters/trace/stdout:stdout_exporter",
31+
"//opencensus/exporters/trace/zipkin:zipkin_exporter",
32+
"//opencensus/trace",
33+
"@civetweb",
34+
"@com_github_jupp0r_prometheus_cpp//pull",
35+
"@com_google_absl//absl/strings",
36+
],
37+
)

examples/http/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Example HTTP server
2+
3+
This example uses OpenCensus to instrument an HTTP server.
4+
5+
Usage:
6+
7+
```shell
8+
bazel run examples/http:server -- 9001
9+
curl -i -H "traceparent: 00-404142434445464748494a4b4c4d4e4f-6162636465666768-01" 127.0.0.1:9001
10+
```
11+
12+
Prometheus metrics can be seen at http://127.0.0.1:8080/metrics
13+
and running Zipkin will show traces, e.g.:
14+
15+
```shell
16+
docker run -p 9411:9411 openzipkin/zipkin
17+
```

examples/http/server.cc

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright 2019, OpenCensus Authors
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+
// Example HTTP server with OpenCensus instrumentation.
16+
17+
#include <cstdlib>
18+
#include <iostream>
19+
#include <memory>
20+
#include <string>
21+
22+
#include "CivetServer.h"
23+
#include "absl/strings/escaping.h"
24+
#include "absl/strings/numbers.h"
25+
#include "absl/strings/str_cat.h"
26+
#include "absl/time/clock.h"
27+
#include "absl/time/time.h"
28+
#include "opencensus/exporters/stats/prometheus/prometheus_exporter.h"
29+
#include "opencensus/exporters/stats/stackdriver/stackdriver_exporter.h"
30+
#include "opencensus/exporters/stats/stdout/stdout_exporter.h"
31+
#include "opencensus/exporters/trace/stackdriver/stackdriver_exporter.h"
32+
#include "opencensus/exporters/trace/stdout/stdout_exporter.h"
33+
#include "opencensus/exporters/trace/zipkin/zipkin_exporter.h"
34+
#include "opencensus/stats/stats.h"
35+
#include "opencensus/trace/propagation/trace_context.h"
36+
#include "opencensus/trace/sampler.h"
37+
#include "opencensus/trace/span.h"
38+
#include "opencensus/trace/trace_config.h"
39+
#include "prometheus/exposer.h"
40+
41+
namespace {
42+
43+
using opencensus::exporters::trace::ZipkinExporter;
44+
using opencensus::exporters::trace::ZipkinExporterOptions;
45+
46+
opencensus::stats::MeasureInt64 HitsMeasure() {
47+
static const opencensus::stats::MeasureInt64 measure =
48+
opencensus::stats::MeasureInt64::Register(
49+
"hits", "Number of hits to the webserver.", "1");
50+
return measure;
51+
}
52+
53+
class CounterHandler : public CivetHandler {
54+
public:
55+
bool handleGet(CivetServer *server, struct mg_connection *conn) {
56+
// Handle incoming trace context.
57+
::opencensus::trace::SpanContext parent;
58+
const char *traceparent = server->getHeader(conn, "traceparent");
59+
if (traceparent != nullptr) {
60+
parent =
61+
opencensus::trace::propagation::FromTraceParentHeader(traceparent);
62+
}
63+
std::cerr << "parent is " << parent.ToString() << "\n";
64+
auto span = parent.IsValid()
65+
? ::opencensus::trace::Span::StartSpanWithRemoteParent(
66+
"Counter", parent)
67+
: ::opencensus::trace::Span::StartSpan("Counter");
68+
69+
const mg_request_info *req = mg_get_request_info(conn);
70+
printf("Got %d headers:\n", req->num_headers);
71+
for (int i = 0; i < req->num_headers; ++i) {
72+
printf(" %s: %s\n", req->http_headers[i].name,
73+
req->http_headers[i].value);
74+
}
75+
76+
// Perform work.
77+
counter_++;
78+
span.AddAnnotation("Incremented counter.", {{"counter_value", counter_}});
79+
mg_printf(conn,
80+
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
81+
"close\r\n\r\n");
82+
mg_printf(conn, "<!DOCTYPE html>\n");
83+
mg_printf(conn, "<html><body>There have been %d hits.</body></html>\n",
84+
counter_);
85+
span.AddAnnotation("Built response.");
86+
opencensus::stats::Record({{HitsMeasure(), 1}});
87+
span.End();
88+
return true;
89+
}
90+
91+
private:
92+
int counter_ = 0;
93+
};
94+
95+
} // namespace
96+
97+
int main(int argc, char **argv) {
98+
// Handle port argument.
99+
int port = 0;
100+
if (argc == 2) {
101+
if (!absl::SimpleAtoi(argv[1], &port)) {
102+
std::cerr << "Invalid port number: \"" << argv[1] << "\"";
103+
return 1;
104+
}
105+
}
106+
107+
// For debugging, register exporters that just write to stdout.
108+
opencensus::exporters::stats::StdoutExporter::Register();
109+
opencensus::exporters::trace::StdoutExporter::Register();
110+
111+
// Use the Prometheus exporter for stats.
112+
auto exporter =
113+
std::make_shared<opencensus::exporters::stats::PrometheusExporter>();
114+
prometheus::Exposer exposer("127.0.0.1:8080");
115+
exposer.RegisterCollectable(exporter);
116+
117+
// Use the Zipkin exporter for tracing.
118+
ZipkinExporterOptions options("http://127.0.0.1:9411/api/v2/spans");
119+
options.service_name = "counter_server";
120+
ZipkinExporter::Register(options);
121+
122+
// Add a View for hits.
123+
HitsMeasure();
124+
const auto hits_view =
125+
opencensus::stats::ViewDescriptor()
126+
.set_name("hits_view")
127+
.set_description("number of hits to the server over time")
128+
.set_measure("hits")
129+
.set_aggregation(opencensus::stats::Aggregation::Sum());
130+
opencensus::stats::View view(hits_view);
131+
assert(view.IsValid());
132+
hits_view.RegisterForExport();
133+
134+
// Start the webserver.
135+
CivetServer server{
136+
{"listening_ports", absl::StrCat(port), "num_threads", "2"}};
137+
CounterHandler handler;
138+
server.addHandler("/", handler);
139+
std::cout << "Server listening on port " << port << "\n";
140+
for (;;) {
141+
absl::SleepFor(absl::Seconds(1));
142+
}
143+
}

0 commit comments

Comments
 (0)