# SSLCertificateKeyFile "/path/to/client.key"
# VerifyPeer false
# </Receiver>
-# <Exporter "example">
-# Host "localhost"
-# Port "4317"
-# </Exporter>
+# Exporter "localhost" "4317"
#</Plugin>
#<Plugin oracle>
=back
-=head2 Plugin C<open_telemetry_collector>
+=head2 Plugin C<open_telemetry>
The I<open_telemetry plugin> implements an OpenTelemetry exporter and receiver
using OTLP. Specifically, it implements a gRPC C<MetricsService> client and
SSLCertificateKeyFile "/path/to/client.key"
VerifyPeer false
</Receiver>
- <Exporter "example">
- Host "localhost"
- Port "4317"
- </Exporter>
+ Exporter "localhost" "4317"
</Plugin>
=over 4
-=item B<Receiver> I<Host> I<Port>
+=item B<Receiver> I<Host> [I<Port>]
The B<Receiver> statement sets the network address and port to which to bind.
Multiple B<Receiver> blocks can be specified to listen on multiple
The argument I<Host> may be a hostname, an IPv4 address, or an IPv6 address.
+The I<Port> argument may be omitted. In that case the default C<"4317"> is
+used.
+
Optionally, B<Receiver> blocks support the following options:
=over 4
=back
-=item B<Exporter> I<Name>
-
-The plugin can export metrics to multiple collectors by specifying multiple
-B<Exporter> blocks. Within the B<Exporter> blocks, the following options are
-available:
-
-=over 4
-
-=item B<Host> I<Address>
-
-Hostname or address to connect to. Defaults to C<localhost>.
+=item B<Exporter> I<Host> [I<Port>]
-=item B<Port> I<Service>
+The B<Exporter> option configures an OTLP export to the given collector
+address. Multiple collectors can be specified using multiple B<Exporter> lines.
-Service name or port number to connect to. Defaults to C<4317>.
+The argument I<Host> may be a hostname, an IPv4 address, or an IPv6 address.
-=back
+The I<Port> argument may be omitted. In that case the default C<"4317"> is
+used.
=back
#include "opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.h"
#include "utils/format_open_telemetry/format_open_telemetry.h"
-#ifndef OT_DEFAULT_HOST
-#define OT_DEFAULT_HOST "localhost"
-#endif
-
#ifndef OT_DEFAULT_PORT
#define OT_DEFAULT_PORT "4317"
#endif
* Private variables
*/
typedef struct {
- char *name;
int reference_count;
char *host;
cb->stub.reset();
- sfree(cb->name);
sfree(cb->host);
sfree(cb->port);
}
int exporter_config(oconfig_item_t *ci) {
+ if (ci->values_num < 1 || ci->values_num > 2 ||
+ ci->values[0].type != OCONFIG_TYPE_STRING ||
+ (ci->values_num > 1 && ci->values[1].type != OCONFIG_TYPE_STRING)) {
+ ERROR("open_telemetry plugin: The \"%s\" config option needs "
+ "one or two string arguments (address and port).",
+ ci->key);
+ return EINVAL;
+ }
+
ot_callback_t *cb = (ot_callback_t *)calloc(1, sizeof(*cb));
if (cb == NULL) {
ERROR("open_telemetry plugin: calloc failed.");
return -1;
}
- cb->reference_count = 1;
- cf_util_get_string(ci, &cb->name);
- cb->host = strdup(OT_DEFAULT_HOST);
- cb->port = strdup(OT_DEFAULT_PORT);
-
- pthread_mutex_init(&cb->mu, /* attr = */ NULL);
-
- for (int i = 0; i < ci->children_num; i++) {
- oconfig_item_t *child = ci->children + i;
-
- int status = 0;
- if (strcasecmp("Host", child->key) == 0)
- status = cf_util_get_string(child, &cb->host);
- else if (strcasecmp("Port", child->key) == 0)
- status = cf_util_get_service(child, &cb->port);
- else {
- ERROR("open_telemetry plugin: invalid config option: %s.", child->key);
- status = -1;
- }
-
- if (status != 0) {
- ot_callback_decref(cb);
- return status;
- }
+ *cb = (ot_callback_t){
+ .reference_count = 1,
+ .host = strdup(ci->values[0].value.string),
+ };
+ if (ci->values_num >= 2) {
+ cb->port = strdup(ci->values[1].value.string);
+ } else {
+ cb->port = strdup(OT_DEFAULT_PORT);
}
+ pthread_mutex_init(&cb->mu, /* attr = */ NULL);
strbuf_t callback_name = STRBUF_CREATE;
- strbuf_printf(&callback_name, "open_telemetry/%s", cb->name);
+ strbuf_printf(&callback_name, "open_telemetry/[%s]:%s", cb->host, cb->port);
user_data_t user_data = {
.data = cb,
#include "opentelemetry/proto/metrics/v1/metrics.pb.h"
#include "opentelemetry/proto/resource/v1/resource.pb.h"
+#ifndef OT_DEFAULT_PORT
+#define OT_DEFAULT_PORT "4317"
+#endif
+
using opentelemetry::proto::collector::metrics::v1::ExportMetricsPartialSuccess;
using opentelemetry::proto::collector::metrics::v1::ExportMetricsServiceRequest;
using opentelemetry::proto::collector::metrics::v1::
grpc::ServerBuilder builder;
- if (listeners.empty()) {
- builder.AddListeningPort(default_addr, auth);
- INFO("open_telemetry plugin: Listening on %s", default_addr.c_str());
- } else {
- for (auto l : listeners) {
- grpc::string addr = l.addr + ":" + l.port;
-
- auto use_ssl = grpc::string("");
- auto a = auth;
- if (l.ssl != nullptr) {
- use_ssl = grpc::string(" (SSL enabled)");
- a = grpc::SslServerCredentials(*l.ssl);
- }
-
- builder.AddListeningPort(addr, a);
- INFO("open_telemetry plugin: Listening on %s%s", addr.c_str(),
- use_ssl.c_str());
+ for (auto l : listeners) {
+ grpc::string addr = l.addr + ":" + l.port;
+
+ auto use_ssl = grpc::string("");
+ auto a = auth;
+ if (l.ssl != nullptr) {
+ use_ssl = grpc::string(" (SSL enabled)");
+ a = grpc::SslServerCredentials(*l.ssl);
}
+
+ builder.AddListeningPort(addr, a);
+ INFO("open_telemetry plugin: Listening on %s%s", addr.c_str(),
+ use_ssl.c_str());
}
builder.RegisterService(&metrics_service);
* collectd plugin interface
*/
int receiver_config(oconfig_item_t *ci) {
- if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
- (ci->values[1].type != OCONFIG_TYPE_STRING)) {
- ERROR("open_telemetry plugin: The `%s` config option needs exactly "
- "two string argument (address and port).",
+ if (ci->values_num < 1 || ci->values_num > 2 ||
+ ci->values[0].type != OCONFIG_TYPE_STRING ||
+ (ci->values_num > 1 && ci->values[1].type != OCONFIG_TYPE_STRING)) {
+ ERROR("open_telemetry plugin: The \"%s\" config option needs "
+ "one or two string arguments (address and port).",
ci->key);
- return -1;
+ return EINVAL;
}
auto listener = Listener();
listener.addr = grpc::string(ci->values[0].value.string);
- listener.port = grpc::string(ci->values[1].value.string);
+ if (ci->values_num >= 2) {
+ listener.port = grpc::string(ci->values[1].value.string);
+ } else {
+ listener.port = grpc::string(OT_DEFAULT_PORT);
+ }
listener.ssl = nullptr;
auto ssl_opts = new grpc::SslServerCredentialsOptions(
ssl_opts->pem_key_cert_pairs.push_back(pkcp);
listener.ssl = ssl_opts;
} else {
- delete (ssl_opts);
+ delete ssl_opts;
}
listeners.push_back(listener);