Coder Social home page Coder Social logo

prometheus-cpp's Introduction

Prometheus Client Library for Modern C++

Bazel CI CMake CI Coverage Status

This library aims to enable Metrics-Driven Development for C++ services. It implements the Prometheus Data Model, a powerful abstraction on which to collect and expose metrics. We offer the possibility for metrics to be collected by Prometheus, but other push/pull collections can be added as plugins.

Usage

See https://jupp0r.github.io/prometheus-cpp for more detailed interface documentation.

#include <prometheus/counter.h>
#include <prometheus/exposer.h>
#include <prometheus/registry.h>

#include <array>
#include <chrono>
#include <cstdlib>
#include <memory>
#include <string>
#include <thread>

int main() {
  using namespace prometheus;

  // create an http server running on port 8080
  Exposer exposer{"127.0.0.1:8080"};

  // create a metrics registry
  // @note it's the users responsibility to keep the object alive
  auto registry = std::make_shared<Registry>();

  // add a new counter family to the registry (families combine values with the
  // same name, but distinct label dimensions)
  //
  // @note please follow the metric-naming best-practices:
  // https://prometheus.io/docs/practices/naming/
  auto& packet_counter = BuildCounter()
                             .Name("observed_packets_total")
                             .Help("Number of observed packets")
                             .Register(*registry);

  // add and remember dimensional data, incrementing those is very cheap
  auto& tcp_rx_counter =
      packet_counter.Add({{"protocol", "tcp"}, {"direction", "rx"}});
  auto& tcp_tx_counter =
      packet_counter.Add({{"protocol", "tcp"}, {"direction", "tx"}});
  auto& udp_rx_counter =
      packet_counter.Add({{"protocol", "udp"}, {"direction", "rx"}});
  auto& udp_tx_counter =
      packet_counter.Add({{"protocol", "udp"}, {"direction", "tx"}});

  // add a counter whose dimensional data is not known at compile time
  // nevertheless dimensional values should only occur in low cardinality:
  // https://prometheus.io/docs/practices/naming/#labels
  auto& http_requests_counter = BuildCounter()
                                    .Name("http_requests_total")
                                    .Help("Number of HTTP requests")
                                    .Register(*registry);

  // ask the exposer to scrape the registry on incoming HTTP requests
  exposer.RegisterCollectable(registry);

  for (;;) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    const auto random_value = std::rand();

    if (random_value & 1) tcp_rx_counter.Increment();
    if (random_value & 2) tcp_tx_counter.Increment();
    if (random_value & 4) udp_rx_counter.Increment();
    if (random_value & 8) udp_tx_counter.Increment();

    const std::array<std::string, 4> methods = {"GET", "PUT", "POST", "HEAD"};
    auto method = methods.at(random_value % methods.size());
    // dynamically calling Family<T>.Add() works but is slow and should be
    // avoided
    http_requests_counter.Add({{"method", method}}).Increment();
  }
  return 0;
}

Requirements

Using prometheus-cpp requires a C++11 compliant compiler. It has been successfully tested with GNU GCC 7.4 on Ubuntu Bionic (18.04) and Visual Studio 2017.

Building

There are two supported ways to build prometheus-cpp - CMake and bazel. Both are tested in CI and should work on master and for all releases.

In case these instructions don't work for you, looking at the GitHub Workflows might help.

via CMake

For CMake builds don't forget to fetch the submodules first. Please note that zlib and libcurl are not provided by the included submodules. In the example below their usage is disabled.

Then build as usual.

# fetch third-party dependencies
git submodule init
git submodule update

mkdir _build
cd _build

# run cmake
cmake .. -DBUILD_SHARED_LIBS=ON -DENABLE_PUSH=OFF -DENABLE_COMPRESSION=OFF

# build
cmake --build . --parallel 4

# run tests
ctest -V

# install the libraries and headers
cmake --install .

via Bazel

Install bazel. Bazel makes it easy to add this repo to your project as a dependency. Just add the following to your WORKSPACE:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
http_archive(
    name = "com_github_jupp0r_prometheus_cpp",
    strip_prefix = "prometheus-cpp-master",
    urls = ["https://github.com/jupp0r/prometheus-cpp/archive/master.zip"],
)

load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories")

prometheus_cpp_repositories()

Then, you can reference this library in your own BUILD file, as demonstrated with the sample server included in this repository:

cc_binary(
    name = "sample_server",
    srcs = ["sample_server.cc"],
    deps = ["@com_github_jupp0r_prometheus_cpp//pull"],
)

When you call prometheus_cpp_repositories() in your WORKSPACE file, you load the following dependencies, if they do not exist yet, into your project:

The list of dependencies is also available from file repositories.bzl.

Packaging

By configuring CPack you can generate an installer like a Debian package (.deb) or RPM (.rpm) for the static or dynamic libraries so they can be easily installed on other systems.

Please refer to the CPack documentation for all available generators and their configuration options.

To generate a Debian package you could follow these steps:

# fetch third-party dependencies
git submodule update --init

# run cmake
cmake -B_build -DCPACK_GENERATOR=DEB -DBUILD_SHARED_LIBS=ON # or OFF for static libraries

# build and package
cmake --build _build --target package --parallel $(nproc)

This will place an appropriately named .deb in the _build folder. To build a RPM package set the CPACK_GENERATOR variable to RPM.

Consuming the installed project

CMake

Consuming prometheus-cpp via CMake is the preferred way because all the dependencies between the three prometheus-cpp libraries are handled correctly.

The cmake/project-import directory contains an example project and minimal CMakeLists.txt.

Ubuntu PPA

The Launchpad prometheus-cpp team provides a PPA for stable versions. Please follow the "Adding this PPA to your system" steps to use it.

vcpkg

The vcpkg package manager contains a prometheus-cpp port which has been tested on Linux, macOS, and Windows.

Conan

Conan package manager contains prometheus-cpp package as well in ConanCenter repository

Plain Makefiles

When manually linking prometheus-cpp the library order matters. The needed libraries depend on the individual use case but the following should work for the pull metrics approach:

-lprometheus-cpp-pull -lprometheus-cpp-core -lz

For the push-workflow please try:

-lprometheus-cpp-push -lprometheus-cpp-core -lcurl -lz

Contributing

Please adhere to the Google C++ Style Guide. Make sure to clang-format your patches before opening a PR. Also make sure to adhere to these commit message guidelines.

You can check out this repo and build the library using

bazel build //...

Run the unit tests using

bazel test //...

There is also an integration test that uses telegraf to scrape a sample server. With telegraf installed, it can be run using

bazel test //pull/tests/integration:scrape-test

Benchmarks

There's a benchmark suite you can run:

bazel run -c opt //core/benchmarks

INFO: Analysed target //core/benchmarks:benchmarks (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //core/benchmarks:benchmarks up-to-date:
  bazel-bin/core/benchmarks/benchmarks
INFO: Elapsed time: 0.356s, Critical Path: 0.01s, Remote (0.00% of the time): [queue: 0.00%, setup: 0.00%, process: 0.00%]
INFO: 0 processes.
INFO: Build completed successfully, 1 total action
INFO: Build completed successfully, 1 total action
2018-11-30 15:13:14
Run on (4 X 2200 MHz CPU s)
CPU Caches:
  L1 Data 32K (x2)
  L1 Instruction 32K (x2)
  L2 Unified 262K (x2)
  L3 Unified 4194K (x1)
-----------------------------------------------------------------------------------
Benchmark                                            Time           CPU Iterations
-----------------------------------------------------------------------------------
BM_Counter_Increment                                13 ns         12 ns   55616469
BM_Counter_Collect                                   7 ns          7 ns   99823170
BM_Gauge_Increment                                  12 ns         12 ns   51511873
BM_Gauge_Decrement                                  12 ns         12 ns   56831098
BM_Gauge_SetToCurrentTime                          184 ns        183 ns    3928964
BM_Gauge_Collect                                     6 ns          6 ns  117223478
BM_Histogram_Observe/0                             134 ns        124 ns    5665310
BM_Histogram_Observe/1                             122 ns        120 ns    5937185
BM_Histogram_Observe/8                             137 ns        135 ns    4652863
BM_Histogram_Observe/64                            143 ns        143 ns    4835957
BM_Histogram_Observe/512                           259 ns        257 ns    2334750
BM_Histogram_Observe/4096                         1545 ns       1393 ns     620754
BM_Histogram_Collect/0                             103 ns        102 ns    5654829
BM_Histogram_Collect/1                             100 ns        100 ns    7015153
BM_Histogram_Collect/8                             608 ns        601 ns    1149652
BM_Histogram_Collect/64                           1438 ns       1427 ns     515236
BM_Histogram_Collect/512                          5178 ns       5159 ns     114619
BM_Histogram_Collect/4096                        33527 ns      33280 ns      20785
BM_Registry_CreateFamily                           320 ns        316 ns    2021567
BM_Registry_CreateCounter/0                        128 ns        128 ns    5487140
BM_Registry_CreateCounter/1                       2066 ns       2058 ns     386002
BM_Registry_CreateCounter/8                       7672 ns       7634 ns      91328
BM_Registry_CreateCounter/64                     63270 ns      62761 ns      10780
BM_Registry_CreateCounter/512                   560714 ns     558328 ns       1176
BM_Registry_CreateCounter/4096                18672798 ns   18383000 ns         35
BM_Summary_Observe/0/iterations:262144            9351 ns       9305 ns     262144
BM_Summary_Observe/1/iterations:262144            9242 ns       9169 ns     262144
BM_Summary_Observe/8/iterations:262144           14344 ns      14195 ns     262144
BM_Summary_Observe/64/iterations:262144          19176 ns      18950 ns     262144
BM_Summary_Collect/0/0                              31 ns         30 ns   24873766
BM_Summary_Collect/1/0                             166 ns        166 ns    4266706
BM_Summary_Collect/8/0                            1040 ns       1036 ns     660527
BM_Summary_Collect/64/0                           4529 ns       4489 ns     155600
BM_Summary_Collect/0/1                              28 ns         28 ns   24866697
BM_Summary_Collect/1/1                             190 ns        188 ns    3930354
BM_Summary_Collect/8/1                            1372 ns       1355 ns     535779
BM_Summary_Collect/64/1                           9901 ns       9822 ns      64632
BM_Summary_Collect/0/8                              29 ns         29 ns   24922651
BM_Summary_Collect/1/8                             217 ns        215 ns    3278381
BM_Summary_Collect/8/8                            2275 ns       2256 ns     282503
BM_Summary_Collect/64/8                          56790 ns      55804 ns      13878
BM_Summary_Collect/0/64                             32 ns         31 ns   22548350
BM_Summary_Collect/1/64                            395 ns        389 ns    1817073
BM_Summary_Collect/8/64                          10187 ns      10064 ns      71928
BM_Summary_Collect/64/64                        374835 ns     373560 ns       1812
BM_Summary_Collect/0/512                            28 ns         28 ns   25234228
BM_Summary_Collect/1/512                          1710 ns       1639 ns     802285
BM_Summary_Collect/8/512                         50355 ns      49335 ns      15975
BM_Summary_Collect/64/512                      2520972 ns    2493417 ns        295
BM_Summary_Collect/0/4096                           31 ns         31 ns   24059034
BM_Summary_Collect/1/4096                         2719 ns       2698 ns     286186
BM_Summary_Collect/8/4096                       121689 ns     119995 ns       5647
BM_Summary_Collect/64/4096                     5660131 ns    5587634 ns        134
BM_Summary_Collect/0/32768                          29 ns         29 ns   22217567
BM_Summary_Collect/1/32768                        4344 ns       4294 ns     138135
BM_Summary_Collect/8/32768                      331563 ns     326403 ns       2017
BM_Summary_Collect/64/32768                   16363553 ns   16038182 ns         44
BM_Summary_Collect/0/262144                         27 ns         27 ns   23923036
BM_Summary_Collect/1/262144                      10457 ns      10332 ns      67690
BM_Summary_Collect/8/262144                     930434 ns     869234 ns        792
BM_Summary_Collect/64/262144                  39217069 ns   39054846 ns         13
BM_Summary_Observe_Common/iterations:262144       5587 ns       5557 ns     262144
BM_Summary_Collect_Common/0                        676 ns        673 ns    1054630
BM_Summary_Collect_Common/1                        709 ns        705 ns     990659
BM_Summary_Collect_Common/8                       1030 ns       1025 ns     685649
BM_Summary_Collect_Common/64                      2066 ns       2055 ns     339969
BM_Summary_Collect_Common/512                     5754 ns       5248 ns     156895
BM_Summary_Collect_Common/4096                   23894 ns      23292 ns      31096
BM_Summary_Collect_Common/32768                  49831 ns      49292 ns      13492
BM_Summary_Collect_Common/262144                128723 ns     126987 ns       5579

Project Status

Stable and used in production.

Parts of the library are instrumented by itself (bytes scraped, number of scrapes, scrape request latencies). There is a working example that's scraped by telegraf as part of integration tests.

FAQ

What scrape formats do you support

Only the Prometheus Text Exposition Format. Support for the protobuf format was removed because it's been removed from Prometheus 2.0.

License

MIT

prometheus-cpp's People

Contributors

0mp avatar david-ray1 avatar drigz avatar flier avatar gjasny avatar gocarlos avatar jameseh96 avatar jerryct avatar jovany-wang avatar jupp0r avatar khabinov avatar krfricke avatar lb5tr avatar ljbade avatar logout22 avatar martinitus avatar mkenigs avatar mlsna avatar mmorel-35 avatar odeits-vidder avatar owenknight-flintpro avatar paroga avatar parsifal-47 avatar pavel-pimenov avatar phallot avatar renovate-bot avatar romain-geissler-1a avatar sbates130272 avatar sjanel avatar thomas-barbier-1a avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

prometheus-cpp's Issues

(gcc4.8.5)When I make, "use of deleted function "happens, How to solve it?

``/home/shiqikai/prometheus-cpp/push/src/gateway.cc: In member function ‘int prometheus::Gateway::push(prometheus::Gateway::PushMode)’:
/home/shiqikai/prometheus-cpp/push/src/gateway.cc:63:34: error: use of deleted function ‘std::basic_stringstream::basic_stringstream(const std::basic_stringstream&)’
auto uri = std::stringstream{};
^
In file included from /home/shiqikai/prometheus-cpp/push/include/prometheus/gateway.h:6:0,
from /home/shiqikai/prometheus-cpp/push/src/gateway.cc:2:
/usr/include/c++/4.8.2/sstream:502:11: note: ‘std::basic_stringstream::basic_stringstream(const std::basic_stringstream&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_stringstream : public basic_iostream<_CharT, _Traits>
^
/usr/include/c++/4.8.2/sstream:502:11: error: use of deleted function ‘std::basic_iostream::basic_iostream(const std::basic_iostream&)’
In file included from /usr/include/c++/4.8.2/sstream:38:0,
from /home/shiqikai/prometheus-cpp/push/include/prometheus/gateway.h:6,
from /home/shiqikai/prometheus-cpp/push/src/gateway.cc:2:
/usr/include/c++/4.8.2/istream:795:11: note: ‘std::basic_iostream::basic_iostream(const std::basic_iostream&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_iostream
^
/usr/include/c++/4.8.2/istream:795:11: error: use of deleted function ‘std::basic_istream::basic_istream(const std::basic_istream&)’
/usr/include/c++/4.8.2/istream:58:11: note: ‘std::basic_istream::basic_istream(const std::basic_istream&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_istream : virtual public basic_ios<_CharT, _Traits>
^
/usr/include/c++/4.8.2/istream:58:11: error: use of deleted function ‘std::basic_ios::basic_ios(const std::basic_ios&)’
In file included from /usr/include/c++/4.8.2/ios:44:0,
from /usr/include/c++/4.8.2/istream:38,
from /usr/include/c++/4.8.2/sstream:38,
from /home/shiqikai/prometheus-cpp/push/include/prometheus/gateway.h:6,
from /home/shiqikai/prometheus-cpp/push/src/gateway.cc:2:
/usr/include/c++/4.8.2/bits/basic_ios.h:66:11: note: ‘std::basic_ios::basic_ios(const std::basic_ios&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_ios : public ios_base
^
In file included from /usr/include/c++/4.8.2/ios:42:0,
from /usr/include/c++/4.8.2/istream:38,
from /usr/include/c++/4.8.2/sstream:38,
from /home/shiqikai/prometheus-cpp/push/include/prometheus/gateway.h:6,
from /home/shiqikai/prometheus-cpp/push/src/gateway.cc:2:
/usr/include/c++/4.8.2/bits/ios_base.h:786:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
ios_base(const ios_base&);

cmake build static library using shared libraries

The static library built using cmake should only use static libraries for its dependencies.
One of the points of using a static library is that no other files need to be installed other than the executable that uses the library.
Currently libprotobuf.so.12 is required.

Thread safety

Hello!

I checked code very briefly and haven't found answer to my question.

Is it possible to use counter from multiple threads which could increment in simultaneously?

Thank you!

I can't build the project in my windows gitbash

I can't build the project in my windows gitbash. Could you help to offer some advice, appreciate for your great support.
errors,

$ cmake ..
-- Building for: Visual Studio 11 2012
-- The C compiler identification is MSVC 17.0.50727.1
-- The CXX compiler identification is MSVC 17.0.50727.1
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/cl.exe
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/cl.exe
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Could NOT find GoogleBenchmark (missing: GoogleBenchmark_LIBRARY GoogleBenchmark_INCLUDE_DIR)
CMake Error at C:/Program Files/CMake/share/cmake-3.12/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
Call Stack (most recent call first):
C:/Program Files/CMake/share/cmake-3.12/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files/CMake/share/cmake-3.12/Modules/FindZLIB.cmake:112 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:17 (find_package)

-- Configuring incomplete, errors occurred!
See also "D:/18.8/prometheus-cpp-master/_build/CMakeFiles/CMakeOutput.log".
See also "D:/18.8/prometheus-cpp-master/_build/CMakeFiles/CMakeError.log".

`promlint` in cpp

Hi, is it possible to build promlint as a lib in c++ on top of this project? Since it will be useful to have it in integration tests for custom servers built in c++. Thanks!

Can we set label value dynamically ?

Hi, jupp0r. I know we can use this to set static label,

auto& second_counter = counter_family.Add(
      {{"another_label", "value"}, {"yet_another_label", "value"}});

what about dynamic labels, for example, I want to set linux errno value as a label. How could I do that ?

Build on Windows Fails with Missing Libs

Windows build has errors indicating that Google Benchmark library is needed. Also is CURL needed?

-- Could NOT find GoogleBenchmark (missing: GoogleBenchmark_LIBRARY GoogleBenchmark_INCLUDE_DIR)
CMake Error at C:/Program Files/CMake/share/cmake-3.12/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
Could NOT find CURL (missing: CURL_LIBRARY CURL_INCLUDE_DIR)

maybe-uninitialized warning with optimized Bazel build

Steps to reproduce (on Debian Buster-like system with GCC 7.3.0):

git clone https://github.com/jupp0r/prometheus-cpp
cd prometheus-cpp
bazel build -c opt //...

This produces the warning:

INFO: From Compiling lib/summary.cc:
In file included from lib/summary.cc:1:0:
bazel-out/k8-opt/bin/_virtual_includes/prometheus_cpp/prometheus/summary.h: In constructor 'prometheus::detail::TimeWindowQuantiles::TimeWindowQuantiles(const std::vector<prometheus::detail::CKMSQuantiles::Quantile>&, std::chrono::_V2::steady_clock::duration, int)':
bazel-out/k8-opt/bin/_virtual_includes/prometheus_cpp/prometheus/summary.h:17:7: warning: '<anonymous>.prometheus::detail::CKMSQuantiles::buffer_' may be used uninitialized in this function [-Wmaybe-uninitialized]
 class CKMSQuantiles {
       ^~~~~~~~~~~~~

The warning seems to only occur without -fPIC. The default fastbuild configuration always builds with -fPIC, but adding -c opt causes each object to be built twice, with and without -fPIC, resulting in this warning. I searched briefly but didn't find anywhere discussing an interaction between -fPIC and -Wmaybe-uninitialized.

Do you think the warning is meaningful? If not, should we suppress it by adding "-Wno-maybe-uninitialized" to copts?

Add simple integration test

It would be really beneficial to have a simple integration test that tests whether prometheus can scrape the sample server:

  1. bulid and start sample_server
  2. start prometheus with a suitable config (see below)
  3. wait a few seconds for prometheus to boot and scrape
  4. query the prometheus REST API to check if metrics are present
  scrape_configs:
  - job_name: 'static'
    scrape_interval: '1s'
    static_configs:
      - targets:
          - 'localhost:8080'

question: calculation of histogram bucket count

hi, thank you for creating this, now I try to embed this library in my app.
question is, doc says histogram buckets are cumulative but implementation of this library does not seems to do so.

for (std::size_t i = 0; i < bucket_counts_.size(); i++) {
    auto& count = bucket_counts_[i];
    auto bucket = histogram->add_bucket();
    bucket->set_cumulative_count(count.Value()); //here
    bucket->set_upper_bound(i == bucket_boundaries_.size()
                                ? std::numeric_limits<double>::infinity()
                                : bucket_boundaries_[i]);
  }

I check another implementation eg. golang, it seems to be cumulative.

	var count uint64
	for i, upperBound := range h.upperBounds {
		count += atomic.LoadUint64(&h.counts[i]) //here
		buckets[i] = &dto.Bucket{
			CumulativeCount: proto.Uint64(count),
			UpperBound:      proto.Float64(upperBound),
		}
	}

is this bug or cpp implementation calculate cumulative counter in another place?

build failed with bazel

I got one example via git clone https://github.com/bazelbuild/examples/, then build the example successfully with bazel.

According to the reference of https://github.com/jupp0r/prometheus-cpp, I made below update for the example. but failed to build, anyone can help to check it or any advices. Thanks.

1. update the hello-world.cc with below content.
#include
#include
#include
#include
#include

#include <prometheus/exposer.h>
#include <prometheus/registry.h>

int main(int argc, char** argv) {
using namespace prometheus;

// create an http server running on port 8080
Exposer exposer{"127.0.0.1:8080"};

// create a metrics registry with component=main labels applied to all its
// metrics
auto registry = std::make_shared();

// add a new counter family to the registry (families combine values with the
// same name, but distinct label dimenstions)
auto& counter_family = BuildCounter()
.Name("time_running_seconds")
.Help("How many seconds is this server running?")
.Labels({{"label", "value"}})
.Register(*registry);

// add a counter to the metric family
auto& second_counter = counter_family.Add(
{{"another_label", "value"}, {"yet_another_label", "value"}});

// ask the exposer to scrape the registry on incoming scrapes
exposer.RegisterCollectable(registry);

for (;;) {
std::this_thread::sleep_for(std::chrono::seconds(1));
// increment the counter by one (second)
second_counter.Increment();
}
return 0;
}

2. add the following to WORKSPACE:
http_archive(
name = "com_github_jupp0r_prometheus_cpp",
strip_prefix = "prometheus-cpp-master",
urls = ["https://github.com/jupp0r/prometheus-cpp/archive/master.zip"],
)

load("@com_github_jupp0r_prometheus_cpp//:repositories.bzl", "prometheus_cpp_repositories")

prometheus_cpp_repositories()

3. reference this library in BUILD file
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = ["@com_github_jupp0r_prometheus_cpp//:prometheus_cpp"],
)

Then build with command "d:\bazel\bazel build //main:hello-world"
got errors as below:

D:\exporter\examples\cpp-tutorial\stage1>d:\bazel\bazel build //main:hello-world
Starting local Bazel server and connecting to it...
.........................
Loading:
Loading: 0 packages loaded
Analyzing: target //main:hello-world (2 packages loaded)
Analyzing: target //main:hello-world (7 packages loaded)
INFO: Analysed target //main:hello-world (9 packages loaded).
INFO: Found 1 target...
Building: no action
[1 / 8] [-----] BazelWorkspaceStatusAction stable-status.txt
[27 / 43] Compiling external/civetweb/src/civetweb.c; 0s local ... (3 actions running)
[27 / 43] Compiling external/civetweb/src/civetweb.c; 2s local ... (4 actions running)
ERROR: C:/users/willl/_bazel_willl/6tqwvxjt/external/civetweb/BUILD.bazel:13:1: undeclared inclusion(s) in rule '@civetweb//:libcivetweb':
this rule is missing dependency declarations for the following files included by 'external/civetweb/src/civetweb.c':
'external/civetweb/src/file_ops.inl'

Target //main:hello-world failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 15.034s, Critical Path: 3.38s
INFO: 2 processes: 2 local.
FAILED: Build did NOT complete successfully
FAILED: Build did NOT complete successfully

D:\exporter\examples\cpp-tutorial\stage1>

BTW, I git clone https://github.com/jupp0r/prometheus-cpp.git, and bazel build //:prometheus_cpp
Got the same errors.

D:\example\prometheus-cpp>d:\bazel\bazel build //:prometheus_cpp
Starting local Bazel server and connecting to it...
.........................
Loading:
Loading: 0 packages loaded
Analyzing: target //:prometheus_cpp (2 packages loaded)
Analyzing: target //:prometheus_cpp (8 packages loaded)
INFO: Analysed target //:prometheus_cpp (8 packages loaded).
INFO: Found 1 target...
Building: no action
[0 / 6] [-----] BazelWorkspaceStatusAction stable-status.txt
[21 / 32] Compiling lib/gauge.cc; 1s local ... (4 actions running)
[24 / 32] Compiling lib/summary.cc; 2s local ... (2 actions running)
[28 / 32] Compiling lib/check_names.cc; 1s local ... (3 actions running)
ERROR: C:/users/willl/_bazel_willl/c3vtfeq2/external/civetweb/BUILD.bazel:13:1: undeclared inclusion(s) in rule '@civetweb//:libcivetweb':
this rule is missing dependency declarations for the following files included by 'external/civetweb/src/civetweb.c':
'external/civetweb/src/file_ops.inl'
Target //:prometheus_cpp failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 11.933s, Critical Path: 2.76s
INFO: 5 processes: 5 local.
FAILED: Build did NOT complete successfully
FAILED: Build did NOT complete successfully

Link CivetWeb dynamically or hide its symbols

The Prometheus C++ client library builds CivetWeb internally, but then exposes all symbols from CivetWeb:

# objdump -TC /usr/local/lib/libprometheus-cpp.so  | egrep -i '(civet|mg_)' | wc -l
118
# objdump -TC /usr/local/lib/libprometheus-cpp.so  | egrep -i '(civet|mg_)' | head
0000000000048290 g    DF .text  0000000000000021  Base        CivetServer::removeWebSocketHandler(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0000000000056250 g    DF .text  0000000000000208  Base        mg_set_request_handler
0000000000048040 g    DF .text  0000000000000002  Base        CivetWebSocketHandler::handleReadyState(CivetServer*, mg_connection*)
0000000000052f20 g    DF .text  000000000000001a  Base        mg_lock_connection
0000000000049810 g    DF .text  00000000000002c6  Base        CivetServer::CivetServer(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, CivetCallbacks const*)
0000000000056700 g    DF .text  0000000000000208  Base        mg_set_auth_handler
000000000004bf40 g    DF .text  000000000000005e  Base        mg_get_ports
00000000000482c0 g    DF .text  0000000000000010  Base        CivetServer::removeAuthHandler(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0000000000048040 g    DF .text  0000000000000002  Base        CivetWebSocketHandler::handleClose(CivetServer*, mg_connection const*)
000000000004be00 g    DF .text  0000000000000047  Base        mg_strcasecmp

This means that an application linked with the Prometheus C++ client library can't use CivetWeb for its own purposes: I can't use the CivetWeb from the Prometheus library (because the header files are not installed) and I can't use another copy unless I can be absolutely sure that I have the exact version that Prometheus uses (or else I'd violate the One Definition Rule).

Old versions of g++/clang crash on name_checker regexes

This is not a bug in the project perse but since it does impact the usability I thought I'd file an issue.

I am building with a relatively ancient g++ (4.8.4) and while it compiles fine when it runs and tries to compile the regex it throws an exception.

Specifying a different regex parser makes the problem go away, I'll submit a PR with that if you are okay accepting that change.

google/protobuf should be submodule

On some platforms, CentOs, the version of googlebuf is much older than is needed to compile.
In particular google/protobuf/util is not installed.

Canonical workspace name?

The WORKSPACE file currently sets name = "prometheus_cpp". This goes against Bazel's advice to use

Bazel [...] advises that a WORKSPACE call itself the reverse of the "canonical" URL of that repository, like com_example_foo_utils.

(source)

I would expect WORKSPACE to set name = "com_github_jupp0r_prometheus_cpp".

Is this intentional or would you consider changing this?

Exposer implicit construction breaks readme examples

Currently the readme says to create an exposer as follows

// create an http server running on port 8080
  auto exposer = Exposer{"127.0.0.1:8080"};

However, the exposer implicitly constructs from the string, and tries to call the copy constructor, which fails.
Potentially avoid this by making the Exposer constructor explicit.

Info:
using c++14 and gcc 6.2 on Ubuntu 14.04

Add human readable metrics output

Right now the metrics exposer only supports protobuf format output. It would be nice to have human readable output for the metrics endpoint on the http exposer. Ideally this would be the official prometheus text format, but as a first step serializing the proto format to json would be quite easy (using protobuf-supplied methods). The distinction which format to serve should be made depending on the Accept http request header.

Add interface documentation

All public interfaces need to be documented, especially regarding to memory management contracts and thread safety.

Could I use this lib in my project on C++ 2003?

Hello guys,

this is not a true issue, it's sort of documentation question: could I use this lib in a very old project (C/C++ 2003)? Are there any constrains?

From what I see in examples, the project is mostly done to be used with C++ >11.

If this lib is not the optimal one for C++2003, could you please advice another prometheus lib for old c++?

Thank you for the help!

Histogram requires buckets to be sorted

This requirement is undocumented and not enforced even in debug builds.

Recommend:

  1. Document requirement
  2. assert(std::is_sorted(std::begin(buckets), std::end(buckets))); during construction of Histogram

Add metrics builder

For the API to be more consistent with other prometheus client libraries, builder pattern should be used instead of the existing factory methods on the registries.

Add CMake files

Bazel is not very wide-spread yet, we should support CMake as a first-class citizen in order to make consuming this library easier.

Split web server into Interface

It would be nice to have an interface (abstract base class) for the webserver or some kind of templating interface to allow a different web server to be used.

I am investigating using this with grpc and it would be nice to just reuse that server instead of running multiple different ones.

Family::Add function should check for existing metric

Without Add function doing existing labels check, it is very inconvenient to work with dynamic label values. I have to introduce a map myself and keep track of created counters. Instead it will be trivial for Family to check.

/metrics data format looks strange

Hi, jupp0r. when using prometheus-cpp, visit page localhost:9090/metrics, I got the following data format:

name: "exposer_bytes_transfered"
help: "bytesTransferred to metrics services"
type: COUNTER
metric {
counter {
value: 326609664
}
}

name: "exposer_total_scrapes"
help: "Number of times metrics were scraped"
type: COUNTER
metric {
counter {
value: 116818
}
}

name: "exposer_request_latencies"
help: "Latencies of serving scrape requests, in milliseconds"
type: HISTOGRAM
metric {
histogram {
sample_count: 116818
sample_sum: 1332
bucket {
cumulative_count: 115487
upper_bound: 1
}

But I found many prometheus exporters don't show data like this. Here's the redis-exporter case:

# HELP a1_aof_rewrite_scheduled
# TYPE a1_aof_rewrite_scheduled gauge
a1_aof_rewrite_scheduled{addr="localhost:30001",alias=""} 0
# HELP a1_blocked_clients
# TYPE a1_blocked_clients gauge
a1_blocked_clients{addr="localhost:30001",alias=""} 0
# HELP a1_cluster_current_epoch
# TYPE a1_cluster_current_epoch gauge
a1_cluster_current_epoch{addr="localhost:30001",alias=""} 6
# HELP a1_cluster_enabled
# TYPE a1_cluster_enabled gauge
a1_cluster_enabled{addr="localhost:30001",alias=""} 1
# HELP a1_cluster_known_nodes
# TYPE a1_cluster_known_nodes gauge
a1_cluster_known_nodes{addr="localhost:30001",alias=""} 6

why is that ? Seems prometheus 2.0 cannot identify the first format when upgrading from prometheus 1.x to 2.0. Error shows:

strconv.ParseFloat: parsing ""exposer_bytes_transfered"": invalid syntax

So how should I change my code to use the second format ? Thanks.

Refactor: extract serialization

Currently, serializing metrics to different formats (length-delim protobuf, json, human readable) is contained in the http exposer component. Other exposers should be able to leverage the same serializations for their purposes, so it would make sense to extract them into separate components.

Metric Name format not enforced

I was able to create a metric "My Counter" and was stuck wondering why Prometheus though my node was down, turns out it violated the metric name requirements. I was surprised this wasn't enforced by the client even in debug mode.

see: https://prometheus.io/docs/concepts/data_model/

The metric name specifies the general feature of a system that is measured (e.g. http_requests_total - the total number of HTTP requests received). It may contain ASCII letters and digits, as well as underscores and colons. It must match the regex [a-zA-Z_:][a-zA-Z0-9_:]*.

how should I create a customized path ?

I know prometheus will automatically scrape /metrics path. But what if I want to create another path and show some data ? How should I do that in prometheus-cpp ?

For example , when I do curl localhost:9090 or curl localhost:9090/info, it can also give me some data I specify.

Thanks.

Label name format not enforced

I was able to create a label "my label" which caused Prometheus to think my node was down. I was surprised this wasn't caught in the client even in debug mode.

see: https://prometheus.io/docs/concepts/data_model/

Label names may contain ASCII letters, numbers, as well as underscores. They must match the regex [a-zA-Z_][a-zA-Z0-9_]*. Label names beginning with __ are reserved for internal use.

can not create http server on AWS instance

Hi jupp0r, I built prometheus-cpp on an AWS instance (ubuntu). Tests passed, but when I tried to run /tests/integration/sample_server. I got the following error:

terminate called after throwing an instance of 'CivetException'
what(): null context when constructing CivetServer. Possible problem binding to port.
Aborted (core dumped)

I changed the line: auto&& exposer = Exposer{"127.0.0.1:8080"} to auto&& exposer = Exposer{"<pulic_dns>:8080"}, where pulic_dns is AWS Public DNS (has format like ecx-xx-xxx-x-xx.us-west-2.compute.amazonaws.com, x is number). I also changed the security to allow access to 8080 on the AWS instance, but did not help.

I would really appreciate your help.

Thread safe registries and families

Currently, instances of registries and families must only be accessed by a single thread. This would force users of this library to implement locking the objects externally, which is quite inconvenient. It would be nice to add locks internally.

git_repository rule doesn't support attribute "branch"

Added dependency to workspace as described in README.md
Got a build error:
//external:prometheus-cpp: no such attribute 'branch' in 'git_repository' rule.

According to bazel doc, there's no such attribute:
https://www.bazel.io/versions/master/docs/be/workspace.html#git_repository

Also got an error:
git_repository rule //external:prometheus-cpp's name field must be a legal workspace name.
According to this https://bazel.build/versions/master/docs/be/functions.html#workspace
and this
bazelbuild/bazel@d21c2d6

repository name must not contain underscores.

Make serializers public

Make json/text/protobuf... serializers public so that we can reuse them without using the Exposer. Use case is to add a /metrics method to an existing HTTP server.

Refactor into smaller, combinable units

I'm interested in using portions of this library, specifically the various metrics implementations. I do not wish to take dependencies on protobuf or civet. I think there's a lot of value in having Counter, Histogram, etc available independently of transport concerns.

It seems reasonable that we might refactor the library into separate components, that would still be combined into one binary but which could also be incorporated individually - for example, in pseudo-cmake:

add_library(metrics, ${METRICS_SRCS})
add_library(metrics_protobuf ${PROMETHEUS_PROTO_SRCS})
add_library(civet_exposer, ${EXPOSER_SRCS})
add_library(prometheus-cpp
  $<TARGET_OBJECTS:metrics>
  $<TARGET_OBJECTS:metrics_protobuf>
  $<TARGET_OBJECTS:civet_exposer>
)

# etc

I haven't looked too deeply into the feasibility, but (as one unfamiliar with the code) it doesn't seem too far-fetched. Is there any interest in supporting this kind of refactor?

Support Prometheus Text Format

Current supported scrape formats are

  1. prometheus' protobuf (default)
  2. json
  3. a human readable format supplied by protobuf DebugString

The official prometheus text format would provide a better alternative to option 3, because it could be scraped by prometheus and because its human-readability is arguably higher.

Could you please write an examples of Histogram ?

Hi, jupp0r. I want to use Histogram in my program. But I can't figure out how to use it such as its method Collect/Observe. Could you please give me an example about building a histogram and set value for it ?

Many Thanks.

build instructions need reworking

Using bazel 0.4.5
on Centos 7.2.1511

bazel build lib:all
bazel test //tests:prometheus_test

I am brand new to Bazel.

$ docker build -t promoteheus-cpp:centos -f Dockerfile.centos .

Step 8/9 : RUN bazel build lib:all
---> Running in 3772e5028199
Extracting Bazel installation...
..........................
WARNING: Sandboxed execution is not supported on your system and thus hermeticity of actions cannot be guaranteed. See http://bazel.build/docs/bazel-user-manual.html#sandboxing for more information. You can turn off this warning via --ignore_unsupported_sandboxing.
ERROR: while parsing 'lib:all': no such package 'lib': BUILD file not found on package path.
____Elapsed time: 2.652s
$cat Dockerfile.centos
FROM centos:7.2.1511
RUN yum update -y &&
yum install -y
curl
gcc
java-1.8.0-openjdk
java-1.8.0-openjdk-devel
unzip
which
RUN curl -L -o /bazel-0.4.5-installer-linux-x86_64.sh
https://github.com/bazelbuild/bazel/releases/download/0.4.5/bazel-0.4.5-installer-linux-x86_64.sh
RUN curl -L -o /prometheus-cpp-master.zip
https://codeload.github.com/jupp0r/prometheus-cpp/zip/master
RUN chmod +x /bazel-0.4.5-installer-linux-x86_64.sh &&
/bazel-0.4.5-installer-linux-x86_64.sh
RUN mkdir /build && cd /build && unzip /prometheus-cpp-master.zip
WORKDIR /build/prometheus-cpp-master
RUN bazel build lib:all
RUN bazel test //tests:prometheus-test

prometheus-cpp doesn't build

Hi,
I'm trying to build 0.4 and get this error:

[ 43%] Building CXX object lib/CMakeFiles/prometheus-cpp.dir/summary.cc.o
In file included from /hab/cache/src/prometheus-cpp-0.4/lib/summary.cc:1:0:
/hab/cache/src/prometheus-cpp-0.4/lib/../include/prometheus/summary.h:49:61: error: field 'quantiles_' has incomplete type 'const std::reference_wrapper<const std::vector<prometheus::detail::CKMSQuantiles::Quantile> >'
   const std::reference_wrapper<const std::vector<Quantile>> quantiles_;
                                                             ^~~~~~~~~~
In file included from /hab/pkgs/core/gcc/7.3.0/20180413214248/include/c++/7.3.0/bits/move.h:54:0,
                 from /hab/pkgs/core/gcc/7.3.0/20180413214248/include/c++/7.3.0/bits/stl_pair.h:59,
                 from /hab/pkgs/core/gcc/7.3.0/20180413214248/include/c++/7.3.0/utility:70,
                 from /hab/pkgs/core/gcc/7.3.0/20180413214248/include/c++/7.3.0/array:38,
                 from /hab/cache/src/prometheus-cpp-0.4/lib/../include/prometheus/summary.h:3,
                 from /hab/cache/src/prometheus-cpp-0.4/lib/summary.cc:1:
/hab/pkgs/core/gcc/7.3.0/20180413214248/include/c++/7.3.0/type_traits:2125:11: note: declaration of 'class std::reference_wrapper<const std::vector<prometheus::detail::CKMSQuantiles::Quantile> >'
     class reference_wrapper;
           ^~~~~~~~~~~~~~~~~
make[2]: *** [lib/CMakeFiles/prometheus-cpp.dir/build.make:303: lib/CMakeFiles/prometheus-cpp.dir/summary.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:155: lib/CMakeFiles/prometheus-cpp.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

This is using GCC 7.3.0, cmake 3.10.2, make 4.2.1, glibc 2.27

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.