Skip to content
This repository was archived by the owner on Aug 19, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8ab1570
Expose API server with metrics in prometheus format.
StevenYCChou Nov 15, 2018
2427bce
Fix indentation and line wrapping.
StevenYCChou Nov 16, 2018
7b3f07e
Remove a redundant test.
StevenYCChou Nov 16, 2018
955a061
Make indentation consistent in Makefile.
StevenYCChou Nov 16, 2018
12b4a86
Fix typo.
StevenYCChou Nov 16, 2018
5c065da
Instrument first metric with opencensus-cpp.
StevenYCChou Nov 21, 2018
c667388
Makefile change
StevenYCChou Dec 6, 2018
cf5f833
remove unused variable.
StevenYCChou Dec 6, 2018
b788df1
expand comments on functions in measures.h
StevenYCChou Dec 6, 2018
e49c64d
remove declaration on internal variable
StevenYCChou Dec 6, 2018
ec5a859
make string declaration consistent
StevenYCChou Dec 6, 2018
bbbd851
add comments on why accessing measure in OAuth2 constructor helps
StevenYCChou Dec 6, 2018
acac889
Change the place to register view.
StevenYCChou Dec 6, 2018
ac7c9ea
Use the right header for prometheus compatible format.
StevenYCChou Dec 6, 2018
5ac289e
Address comments on measurement organization.
StevenYCChou Dec 7, 2018
d8b3e37
fix format in test file.
StevenYCChou Dec 7, 2018
93790ed
revert header/constructor because no need anymore.
StevenYCChou Dec 7, 2018
786245f
Wrap opencensus related code into a class.
StevenYCChou Dec 7, 2018
c22faac
Move util function into Metrics Class.
StevenYCChou Dec 7, 2018
cdfe9c1
remove explicit dependency on prometheus-cpp.
StevenYCChou Dec 7, 2018
7514b25
Clean up prometheus-cpp dependency on gitmodules as well.
StevenYCChou Dec 7, 2018
4f37882
Revert submodules on prometheus-cpp.
StevenYCChou Dec 7, 2018
96b268a
Revert chnage for prometheus-cpp.
StevenYCChou Dec 7, 2018
64929c8
Flush metrics only within one test, and add comments.
StevenYCChou Dec 7, 2018
88830d0
Avoid using string_view for constant string.
StevenYCChou Dec 7, 2018
6ee8ab8
Use constexpr consistently.
StevenYCChou Dec 10, 2018
bee8a32
Refactor code, fix tests which is not idempotent.
StevenYCChou Dec 10, 2018
2687728
initialize export related object every time to be safe - because we d…
StevenYCChou Dec 10, 2018
5c6526e
reorder variable definition.
StevenYCChou Dec 10, 2018
546958f
Use constexpr const.
StevenYCChou Dec 10, 2018
775737c
Add metrics tests on GCE Api Request Errors.
StevenYCChou Dec 11, 2018
fc935e6
fix format.
StevenYCChou Dec 11, 2018
1fe4649
Fix format on namespace.
StevenYCChou Dec 12, 2018
1099767
Fix typo.
StevenYCChou Dec 12, 2018
1e56d36
Address feedbacks.
StevenYCChou Dec 14, 2018
d6c6ac3
Add const.
StevenYCChou Dec 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
path = lib/googletest
url = https://github.com/google/googletest
ignore = dirty
[submodule "lib/opencensus-cpp"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm always wary of targeting an untagged and unreleased commit. We can fix this later, but just wanted to note this as a concern.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acknowledged. I just follow the pattern we used on other submodules. Once opencensus-cpp offically release their new version, we should check in that specific version. for now, I targeted on a commit which includes all the functionality we need, including prometheus-exporter.

path = lib/opencensus-cpp
url = https://github.com/census-instrumentation/opencensus-cpp
ignore = dirty
1 change: 1 addition & 0 deletions lib/opencensus-cpp
Submodule opencensus-cpp added at f44923
1 change: 1 addition & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
init-submodules
build-cpp-netlib
build-yaml-cpp
build-opencensus-cpp
metadatad
100 changes: 91 additions & 9 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ NETWORK_URI_DIR=$(CPP_NETLIB_DIR)/deps/uri
NETWORK_URI_LIBDIR=$(NETWORK_URI_DIR)/src
YAML_CPP_DIR=$(LIBDIR)/yaml-cpp
YAML_CPP_LIBDIR=$(YAML_CPP_DIR)
SUBMODULE_DIRS=$(CPP_NETLIB_DIR) $(YAML_CPP_DIR)
OPENCENSUS_CPP_DIR=$(LIBDIR)/opencensus-cpp
OPENCENSUS_CPP_OPENCENSUS_DIR=$(OPENCENSUS_CPP_DIR)/opencensus
OPENCENSUS_CPP_OPENCENSUS_LIBDIR=$(OPENCENSUS_CPP_OPENCENSUS_DIR)
OPENCENSUS_CPP_ABSL_INCLUDEDIR=$(OPENCENSUS_CPP_DIR)/abseil-src
OPENCENSUS_CPP_ABSL_LIBDIR=$(OPENCENSUS_CPP_DIR)/abseil-build/absl
OPENCENSUS_CPP_PROMETHEUS_CPP_DIR=$(OPENCENSUS_CPP_DIR)/prometheus-src
OPENCENSUS_CPP_PROMETHEUS_CPP_CORE_DIR=$(OPENCENSUS_CPP_PROMETHEUS_CPP_DIR)/core
OPENCENSUS_CPP_PROMETHEUS_CPP_CORE_LIBDIR=$(OPENCENSUS_CPP_DIR)/prometheus-build/core
SUBMODULE_DIRS=$(CPP_NETLIB_DIR) $(YAML_CPP_DIR) $(OPENCENSUS_CPP_DIR)

GIT=git
GIT_VERSION=$(shell $(GIT) --version | grep -oh '[0-9]\+\.[0-9]\+\.[0-9]\+')
Expand All @@ -33,14 +41,48 @@ CMAKE=cmake
CPPFLAGS=\
-DAGENT_VERSION='$(PKG_VERSION)-$(PKG_RELEASE)' \
-DENABLE_DOCKER_METADATA \
-I$(CPP_NETLIB_DIR) -I$(NETWORK_URI_DIR)/include -I$(YAML_CPP_DIR)/include
-I$(CPP_NETLIB_DIR) -I$(NETWORK_URI_DIR)/include -I$(YAML_CPP_DIR)/include \
-I$(OPENCENSUS_CPP_DIR) -I$(OPENCENSUS_CPP_ABSL_INCLUDEDIR) \
-I$(OPENCENSUS_CPP_PROMETHEUS_CPP_CORE_DIR)/include
CXXFLAGS=\
-std=c++11 -g -pthread -Wno-write-strings -Wno-deprecated
LDFLAGS=-L$(CPP_NETLIB_LIBDIR) -L$(NETWORK_URI_LIBDIR) -L$(YAML_CPP_LIBDIR)
LDFLAGS=\
-L$(CPP_NETLIB_LIBDIR) \
-L$(NETWORK_URI_LIBDIR) \
-L$(YAML_CPP_LIBDIR) \
-L$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/stats \
-L$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/context \
-L$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/exporters/stats/prometheus \
-L$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/trace \
-L$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/tags \
-L$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/common/internal \
-L$(OPENCENSUS_CPP_PROMETHEUS_CPP_CORE_LIBDIR) \
-L$(OPENCENSUS_CPP_ABSL_LIBDIR)/numeric \
-L$(OPENCENSUS_CPP_ABSL_LIBDIR)/strings \
-L$(OPENCENSUS_CPP_ABSL_LIBDIR)/synchronization \
-L$(OPENCENSUS_CPP_ABSL_LIBDIR)/time \
-L$(OPENCENSUS_CPP_ABSL_LIBDIR)/debugging \
-L$(OPENCENSUS_CPP_ABSL_LIBDIR)/base
LDLIBS=\
-lcppnetlib-client-connections -lcppnetlib-server-parsers -lnetwork-uri \
-lboost_program_options -lboost_system -lboost_thread -lboost_filesystem \
-lpthread -lyajl -lssl -lcrypto -lyaml-cpp
-lpthread -lyajl -lssl -lcrypto -lyaml-cpp \
-lopencensus_exporters_stats_prometheus \
-lopencensus_exporters_stats_prometheus_utils \
-lopencensus_stats_core -lopencensus_stats_recording \
-lopencensus_tags -lopencensus_tags_context_util \
-lopencensus_context \
-lopencensus_trace_context_util \
-lopencensus_trace_with_span \
-lopencensus_trace \
-lopencensus_common_random \
-lprometheus-cpp-core \
-labsl_strings -labsl_synchronization -labsl_time \
-labsl_int128 \
-labsl_stacktrace -labsl_symbolize \
-labsl_demangle_internal -labsl_internal_debugging_internal \
-labsl_base -labsl_dynamic_annotations -labsl_internal_spinlock_wait \
-labsl_internal_malloc_internal -labsl_internal_throw_delegate
SED_EXTRA=-e 's/-Wall/-Wall -Wno-deprecated/'

UNAME_S=$(shell uname -s)
Expand Down Expand Up @@ -71,6 +113,7 @@ SRCS=\
kubernetes.cc \
resource.cc \
oauth2.cc \
metrics.cc \
logging.cc \
local_stream_http.cc \
local_stream_delegate.cc \
Expand All @@ -88,7 +131,33 @@ CPP_NETLIB_LIBS=\
$(NETWORK_URI_LIBDIR)/libnetwork-uri.a
YAML_CPP_LIBS=\
$(YAML_CPP_LIBDIR)/libyaml-cpp.a
LIBS=$(CPP_NETLIB_LIBS) $(YAML_CPP_LIBS)
OPENCENSUS_CPP_LIBS=\
$(OPENCENSUS_CPP_ABSL_LIBDIR)/base/libabsl_base.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/base/libabsl_internal_malloc_internal.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/base/libabsl_internal_throw_delegate.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/base/libabsl_internal_spinlock_wait.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/base/libabsl_dynamic_annotations.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/debugging/libabsl_demangle_internal.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/debugging/libabsl_internal_debugging_internal.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/debugging/libabsl_stacktrace.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/debugging/libabsl_symbolize.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/numeric/libabsl_int128.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/synchronization/libabsl_synchronization.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/strings/libabsl_strings.a \
$(OPENCENSUS_CPP_ABSL_LIBDIR)/time/libabsl_time.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/exporters/stats/prometheus/libopencensus_exporters_stats_prometheus.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/exporters/stats/prometheus/libopencensus_exporters_stats_prometheus_utils.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/stats/libopencensus_stats_core.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/context/libopencensus_context.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/tags/libopencensus_tags.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/tags/libopencensus_tags_context_util.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/trace/libopencensus_trace.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/trace/libopencensus_trace_with_span.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/trace/libopencensus_trace_context_util.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/context/libopencensus_context.a \
$(OPENCENSUS_CPP_OPENCENSUS_LIBDIR)/common/internal/libopencensus_common_random.a \
$(OPENCENSUS_CPP_PROMETHEUS_CPP_CORE_LIBDIR)/libprometheus-cpp-core.a
LIBS=$(CPP_NETLIB_LIBS) $(YAML_CPP_LIBS) $(OPENCENSUS_CPP_LIBS)

sbindir=/opt/stackdriver/metadata/sbin
INSTALL=/usr/bin/install
Expand Down Expand Up @@ -167,7 +236,7 @@ clean:
$(RM) metadatad $(OBJS)

purge: clean
$(RM) -r init-submodules build-cpp-netlib build-yaml-cpp
$(RM) -r init-submodules build-cpp-netlib build-yaml-cpp build-opencensus-cpp
(cd .. && git submodule deinit -f $(SUBMODULE_DIRS:../%=%))

init-submodules:
Expand Down Expand Up @@ -217,12 +286,25 @@ build-yaml-cpp: $(YAML_CPP_DIR)/Makefile
$(MAKE)
touch build-yaml-cpp

cpp-netlib: $(CPP_NETLIB_LIBS)
$(OPENCENSUS_CPP_DIR)/Makefile: init-submodules
cd $(OPENCENSUS_CPP_DIR) && \
$(CMAKE) -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-std=c++11 \
-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ \
-DBUILD_TESTING=OFF

$(OPENCENSUS_CPP_LIBS): build-opencensus-cpp

build-opencensus-cpp: $(OPENCENSUS_CPP_DIR)/Makefile
cd $(OPENCENSUS_CPP_DIR) && \
$(MAKE)
touch build-opencensus-cpp

cpp-netlib: $(CPP_NETLIB_LIBS)
yaml-cpp: $(YAML_CPP_LIBS)
opencensus-cpp: $(OPENCENSUS_CPP_LIBS)

submodules: cpp-netlib yaml-cpp
submodules: cpp-netlib yaml-cpp opencensus-cpp

all: submodules metadatad

.PHONY: all submodules cpp-netlib yaml-cpp purge clean install deb rpm
.PHONY: all submodules cpp-netlib yaml-cpp opencensus-cpp purge clean install deb rpm
20 changes: 20 additions & 0 deletions src/api_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "configuration.h"
#include "health_checker.h"
#include "http_common.h"
#include "metrics.h"
#include "logging.h"
#include "store.h"

Expand Down Expand Up @@ -84,6 +85,11 @@ MetadataApiServer::MetadataApiServer(const Configuration& config,
std::shared_ptr<HttpServer::connection> conn) {
HandleHealthz(request, conn);
}},
{{"GET", "/metrics"},
[=](const HttpServer::request& request,
std::shared_ptr<HttpServer::connection> conn) {
HandleMetrics(request, conn);
}},
}, config_.VerboseLogging()),
server_(
HttpServer::options(dispatcher_)
Expand Down Expand Up @@ -200,4 +206,18 @@ void MetadataApiServer::HandleHealthz(
}
}

void MetadataApiServer::HandleMetrics(
const HttpServer::request& request,
std::shared_ptr<HttpServer::connection> conn) {
std::string response =
::google::Metrics::SerializeMetricsToPrometheusTextFormat();
conn->set_status(HttpServer::connection::ok);
conn->set_headers(std::map<std::string, std::string>({
{"Connection", "close"},
{"Content-Length", std::to_string(response.size())},
{"Content-Type", "text/plain; version=0.0.4"},
}));
conn->write(response);
}

} // namespace google
2 changes: 2 additions & 0 deletions src/api_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class MetadataApiServer {
std::shared_ptr<HttpServer::connection> conn);
void HandleHealthz(const HttpServer::request& request,
std::shared_ptr<HttpServer::connection> conn);
void HandleMetrics(const HttpServer::request& request,
std::shared_ptr<HttpServer::connection> conn);

const Configuration& config_;
const HealthChecker* health_checker_;
Expand Down
2 changes: 2 additions & 0 deletions src/metadatad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "docker.h"
#include "instance.h"
#include "kubernetes.h"
#include "metrics.h"
#include "time.h"

namespace google {
Expand Down Expand Up @@ -75,6 +76,7 @@ int main(int ac, char** av) {
return parse_result < 0 ? 0 : parse_result;
}

::google::Metrics::RegisterAllViewsForExport();
google::MetadataAgent server(config);

google::InstanceUpdater instance_updater(config, server.mutable_store());
Expand Down
88 changes: 88 additions & 0 deletions src/metrics.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2018 Google Inc.
*
* 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
*
* 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.
**/

#include "metrics.h"

#include <absl/strings/string_view.h>
#include <opencensus/exporters/stats/prometheus/prometheus_exporter.h>
#include <opencensus/stats/stats.h>
#include <prometheus/text_serializer.h>

namespace google {

namespace {

constexpr const char kCount[] = "1";

} // namespace

ABSL_CONST_INIT const absl::string_view
kGceApiRequestErrors =
"container.googleapis.com/internal/metadata_agent/gce_api_request_errors";

void Metrics::RegisterAllViewsForExport() {
// Access metrics used by views to ensure metrics are initalized.
GceApiRequestErrors();

// Register all the views for export.
//
// To avoid view registration throwing error, when adding a new view, register
// measures used by this view in the section above.
GceApiRequestErrorsCumulative().RegisterForExport();
}

void Metrics::RecordGceApiRequestErrors(int64_t value,
const std::string& method) {
::opencensus::stats::Record(
{{GceApiRequestErrors(), value}},
{{MethodTagKey(), method}});
};

const ::opencensus::stats::ViewDescriptor&
Metrics::GceApiRequestErrorsCumulative() {
const static ::opencensus::stats::ViewDescriptor descriptor =
::opencensus::stats::ViewDescriptor()
.set_name("gce_api_request_errors")
.set_measure(kGceApiRequestErrors)
.set_aggregation(::opencensus::stats::Aggregation::Count())
.add_column(MethodTagKey());
return descriptor;
}

std::string Metrics::SerializeMetricsToPrometheusTextFormat() {
static const auto* const text_serializer =
new ::prometheus::TextSerializer();
static auto* const exporter =
new ::opencensus::exporters::stats::PrometheusExporter();
return text_serializer->Serialize(exporter->Collect());
}

::opencensus::stats::MeasureInt64 Metrics::GceApiRequestErrors() {
static const auto measure =
::opencensus::stats::MeasureInt64::Register(
kGceApiRequestErrors,
"Number of API request errors encountered.",
kCount);
return measure;
}

::opencensus::stats::TagKey Metrics::MethodTagKey() {
static const auto method_tag_key =
::opencensus::stats::TagKey::Register("method");
return method_tag_key;
}

} // namespace google
54 changes: 54 additions & 0 deletions src/metrics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2018 Google Inc.
*
* 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
*
* 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.
**/

#ifndef METADATA_AGENT_METRICS_H_
#define METADATA_AGENT_METRICS_H_

#include <opencensus/stats/stats.h>
#include <string>

namespace google {

class Metrics {
public:
// Register all the view descriptors declared above as view for export.
static void RegisterAllViewsForExport();

static void RecordGceApiRequestErrors(int64_t value, const std::string& method);

// View Descriptor accessors. If the view descriptor variable is not
// initialized, these methods will initialize the variable.
static const ::opencensus::stats::ViewDescriptor& GceApiRequestErrorsCumulative();

static std::string SerializeMetricsToPrometheusTextFormat();

private:
// Measure accessors. If the measure variable is not initialized, these methods
// will initialize the variable.
//
// Reference of measure: https://opencensus.io/stats/measure/
static ::opencensus::stats::MeasureInt64 GceApiRequestErrors();

// Tag key accessors. If the tag key variable is not initialized, these methods
// will initialize the variable.
//
// Reference of measure: https://opencensus.io/tag/key/
static ::opencensus::stats::TagKey MethodTagKey();
};

} // namespace google

#endif /* METADATA_AGENT_METRICS_H_ */
Loading