]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
open_telemetry plugin: Combine the *open_telemetry_collector* and *write_open_telemet...
authorFlorian Forster <octo@collectd.org>
Fri, 2 Feb 2024 12:21:17 +0000 (13:21 +0100)
committerFlorian Forster <octo@collectd.org>
Tue, 20 Feb 2024 14:28:50 +0000 (15:28 +0100)
Makefile.am
configure.ac
src/collectd.conf.in
src/collectd.conf.pod
src/open_telemetry.cc [new file with mode: 0644]
src/open_telemetry_exporter.cc [moved from src/write_open_telemetry.cc with 91% similarity]
src/open_telemetry_receiver.cc [moved from src/open_telemetry_collector.cc with 94% similarity]

index 82d476aa2b98cabcf6e688e39b27346f03955755..dbc9b1c0a7d5929362db6ed22e8deabad47d5081 100644 (file)
@@ -484,7 +484,7 @@ libformat_influxdb_la_SOURCES = \
        src/utils/format_influxdb/format_influxdb.c \
        src/utils/format_influxdb/format_influxdb.h
 
-if BUILD_PLUGIN_WRITE_OPEN_TELEMETRY
+if BUILD_PLUGIN_OPEN_TELEMETRY
 noinst_LTLIBRARIES += libformat_open_telemetry.la
 libformat_open_telemetry_la_SOURCES = \
        src/utils/format_open_telemetry/format_open_telemetry.cc \
@@ -1744,22 +1744,17 @@ openvpn_la_SOURCES = src/openvpn.c
 openvpn_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
-if BUILD_PLUGIN_OPEN_TELEMETRY_COLLECTOR
-pkglib_LTLIBRARIES += open_telemetry_collector.la
-open_telemetry_collector_la_SOURCES = src/open_telemetry_collector.cc \
-                                     opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc \
-                                     opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.h \
-                                     opentelemetry/proto/collector/metrics/v1/metrics_service.pb.cc \
-                                     opentelemetry/proto/collector/metrics/v1/metrics_service.pb.h \
-                                     opentelemetry/proto/common/v1/common.pb.cc \
-                                     opentelemetry/proto/common/v1/common.pb.h \
-                                     opentelemetry/proto/metrics/v1/metrics.pb.cc \
-                                     opentelemetry/proto/metrics/v1/metrics.pb.h \
-                                     opentelemetry/proto/resource/v1/resource.pb.cc \
-                                     opentelemetry/proto/resource/v1/resource.pb.h
-open_telemetry_collector_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS)
-open_telemetry_collector_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS)
-open_telemetry_collector_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS)
+if BUILD_PLUGIN_OPEN_TELEMETRY
+pkglib_LTLIBRARIES += open_telemetry.la
+open_telemetry_la_SOURCES = \
+       src/open_telemetry.cc \
+       src/open_telemetry_exporter.cc \
+       src/open_telemetry_receiver.cc \
+       opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc \
+       opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.h
+open_telemetry_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS)
+open_telemetry_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS)
+open_telemetry_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS) libformat_open_telemetry.la
 endif
 
 if BUILD_PLUGIN_ORACLE
@@ -2377,16 +2372,6 @@ write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS)
 write_mongodb_la_LIBADD = $(BUILD_WITH_LIBMONGOC_LIBS)
 endif
 
-if BUILD_PLUGIN_WRITE_OPEN_TELEMETRY
-pkglib_LTLIBRARIES += write_open_telemetry.la
-write_open_telemetry_la_SOURCES = src/write_open_telemetry.cc \
-                                 opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc \
-                                 opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.h
-write_open_telemetry_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS)
-write_open_telemetry_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS)
-write_open_telemetry_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) libformat_open_telemetry.la
-endif
-
 if BUILD_PLUGIN_WRITE_PROMETHEUS
 pkglib_LTLIBRARIES += write_prometheus.la
 write_prometheus_la_SOURCES = src/write_prometheus.c
@@ -2535,7 +2520,7 @@ types.pb.cc: $(srcdir)/proto/types.proto
 endif
 endif
 
-if BUILD_PLUGIN_WRITE_OPEN_TELEMETRY
+if BUILD_PLUGIN_OPEN_TELEMETRY
 BUILT_SOURCES += \
        opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc \
        opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.h \
index 410580069189723bdb841306e11a04ed342ce8bf..9e60e173a27d065999ba501613b46d33c0b4af3e 100644 (file)
@@ -6841,7 +6841,7 @@ plugin_nut="$with_libupsclient"
 plugin_olsrd="yes"
 plugin_onewire="$with_libowcapi"
 plugin_openldap="$with_libldap"
-plugin_open_telemetry_collector="yes"
+plugin_open_telemetry="yes"
 plugin_openvpn="yes"
 plugin_oracle="$with_oracle"
 plugin_ovs_events="no"
@@ -6906,7 +6906,6 @@ plugin_write_influxdb_udp="yes"
 plugin_write_kafka="$with_librdkafka"
 plugin_write_log="no"
 plugin_write_mongodb="$with_libmongoc"
-plugin_write_open_telemetry="yes"
 plugin_write_prometheus="no"
 plugin_write_redis="yes"
 plugin_write_riemann="$with_libriemann_client"
@@ -7177,26 +7176,22 @@ fi
 
 if test "x$GRPC_CPP_PLUGIN" = "x"; then
   plugin_grpc="no (grpc_cpp_plugin not found)"
-  plugin_open_telemetry_collector="no (grpc_cpp_plugin not found)"
-  plugin_write_open_telemetry="no (grpc_cpp_plugin not found)"
+  plugin_open_telemetry="no (grpc_cpp_plugin not found)"
 fi
 if test "x$have_protoc3" != "xyes"; then
   plugin_grpc="no (protoc3 not found)"
-  plugin_open_telemetry_collector="no (protoc3 not found)"
-  plugin_write_open_telemetry="no (protoc3 not found)"
+  plugin_open_telemetry="no (protoc3 not found)"
 fi
 if test "x$with_libprotobuf" != "xyes"; then
   plugin_grpc="no (libprotobuf not found)"
-  plugin_open_telemetry_collector="no (libprotobuf not found)"
-  plugin_write_open_telemetry="no (libprotobuf not found)"
+  plugin_open_telemetry="no (libprotobuf not found)"
 fi
 if test "x$with_libgrpcpp" != "xyes"; then
   plugin_grpc="no (libgrpc++ not found)"
-  plugin_open_telemetry_collector="no (libgrpc++ not found)"
-  plugin_write_open_telemetry="no (libgrpc++ not found)"
+  plugin_open_telemetry="no (libgrpc++ not found)"
 fi
 if test "x$protoc3_optional" = "xno"; then
-  plugin_write_open_telemetry="no (protoc does not support optional fields)"
+  plugin_open_telemetry="no (protoc does not support optional fields)"
 fi
 
 if test "x$have_getifaddrs" = "xyes"; then
@@ -7553,7 +7548,7 @@ AC_PLUGIN([olsrd],               [$plugin_olsrd],             [olsrd statistics]
 AC_PLUGIN([onewire],             [$plugin_onewire],           [OneWire sensor statistics])
 AC_PLUGIN([openldap],            [$plugin_openldap],          [OpenLDAP statistics])
 AC_PLUGIN([openvpn],             [$plugin_openvpn],           [OpenVPN client statistics])
-AC_PLUGIN([open_telemetry_collector], [$plugin_open_telemetry_collector], [OpenTelemetry Collector])
+AC_PLUGIN([open_telemetry],      [$plugin_open_telemetry],    [OpenTelemetry exporter/receiver])
 AC_PLUGIN([oracle],              [$plugin_oracle],            [Oracle plugin])
 AC_PLUGIN([ovs_events],          [$plugin_ovs_events],        [OVS events plugin])
 AC_PLUGIN([ovs_stats],           [$plugin_ovs_stats],         [OVS statistics plugin])
@@ -7618,7 +7613,6 @@ AC_PLUGIN([write_influxdb_udp],  [$plugin_write_influxdb_udp],[Influxdb udp outp
 AC_PLUGIN([write_kafka],         [$plugin_write_kafka],       [Kafka output plugin])
 AC_PLUGIN([write_log],           [$plugin_write_log],         [Log output plugin])
 AC_PLUGIN([write_mongodb],       [$plugin_write_mongodb],     [MongoDB output plugin])
-AC_PLUGIN([write_open_telemetry],[$plugin_write_open_telemetry],[Write OpenTelemetry plugin])
 AC_PLUGIN([write_prometheus],    [$plugin_write_prometheus],  [Prometheus write plugin])
 AC_PLUGIN([write_redis],         [$plugin_write_redis],       [Redis output plugin])
 AC_PLUGIN([write_riemann],       [$plugin_write_riemann],     [Riemann output plugin])
@@ -8001,6 +7995,7 @@ AC_MSG_RESULT([    nut . . . . . . . . . $enable_nut])
 AC_MSG_RESULT([    olsrd . . . . . . . . $enable_olsrd])
 AC_MSG_RESULT([    onewire . . . . . . . $enable_onewire])
 AC_MSG_RESULT([    openldap  . . . . . . $enable_openldap])
+AC_MSG_RESULT([    open_telemetry  . . . $enable_open_telemetry])
 AC_MSG_RESULT([    openvpn . . . . . . . $enable_openvpn])
 AC_MSG_RESULT([    oracle  . . . . . . . $enable_oracle])
 AC_MSG_RESULT([    ovs_events  . . . . . $enable_ovs_events])
@@ -8065,7 +8060,6 @@ AC_MSG_RESULT([    write_influxdb_udp. . $enable_write_influxdb_udp])
 AC_MSG_RESULT([    write_kafka . . . . . $enable_write_kafka])
 AC_MSG_RESULT([    write_log . . . . . . $enable_write_log])
 AC_MSG_RESULT([    write_mongodb . . . . $enable_write_mongodb])
-AC_MSG_RESULT([    write_open_telemetry  $enable_write_open_telemetry])
 AC_MSG_RESULT([    write_prometheus. . . $enable_write_prometheus])
 AC_MSG_RESULT([    write_redis . . . . . $enable_write_redis])
 AC_MSG_RESULT([    write_riemann . . . . $enable_write_riemann])
index 10ce892dcc60f329af2b28565ab2cbf9ba87c564..89a2212f414d0e793775fb6f09aa00c137fe737f 100644 (file)
 #@BUILD_PLUGIN_OLSRD_TRUE@LoadPlugin olsrd
 #@BUILD_PLUGIN_ONEWIRE_TRUE@LoadPlugin onewire
 #@BUILD_PLUGIN_OPENLDAP_TRUE@LoadPlugin openldap
+#@BUILD_PLUGIN_OPEN_TELEMETRY_TRUE@LoadPlugin open_telemetry
 #@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
 #@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
 #@BUILD_PLUGIN_OVS_EVENTS_TRUE@LoadPlugin ovs_events
 #@BUILD_PLUGIN_WRITE_KAFKA_TRUE@LoadPlugin write_kafka
 #@BUILD_PLUGIN_WRITE_LOG_TRUE@LoadPlugin write_log
 #@BUILD_PLUGIN_WRITE_MONGODB_TRUE@LoadPlugin write_mongodb
-#@BUILD_PLUGIN_WRITE_OPEN_TELEMETRY_TRUE@LoadPlugin write_open_telemetry
 #@BUILD_PLUGIN_WRITE_PROMETHEUS_TRUE@LoadPlugin write_prometheus
 #@BUILD_PLUGIN_WRITE_REDIS_TRUE@LoadPlugin write_redis
 #@BUILD_PLUGIN_WRITE_RIEMANN_TRUE@LoadPlugin write_riemann
 #      CollectUserCount false
 #</Plugin>
 
-#<Plugin open_telemetry_collector>
-#  <Listen "0.0.0.0" "4317">
+#<Plugin open_telemetry>
+#  <Receiver "0.0.0.0" "4317">
 #    EnableSSL false
 #    SSLCACertificateFile "/path/to/root.pem"
 #    SSLCertificateFile "/path/to/client.pem"
 #    SSLCertificateKeyFile "/path/to/client.key"
 #    VerifyPeer false
-#  </Listen>
+#  </Receiver>
+#  <Exporter "example">
+#    Host "localhost"
+#    Port "4317"
+#  </Exporter>
 #</Plugin>
 
 #<Plugin oracle>
 #      </Node>
 #</Plugin>
 
-#<Plugin write_open_telemetry>
-#  <Node "example">
-#    Host "localhost"
-#    Port "4317"
-#  </Node>
-#</Plugin>
-
 #<Plugin write_prometheus>
 #      Port "9103"
 #</Plugin>
index 8aa027d2d469fd5e289e806618e86f09be6c09ab..12b39ebd942d9a973e1945c4c751ac43cfb941df 100644 (file)
@@ -7155,21 +7155,38 @@ can be configured independently from that option. Defaults to B<false>.
 
 =head2 Plugin C<open_telemetry_collector>
 
-The I<open_telemetry_collector plugin> implements an OpenTelemetry Collector.
-Specifically, it implements a gRPC C<MetricsService>.
+The I<open_telemetry plugin> implements an OpenTelemetry exporter and receiver
+using OTLP. Specifically, it implements a gRPC C<MetricsService> client and
+server.
+
+B<Synopsis:>
+
+  <Plugin open_telemetry>
+    <Receiver "0.0.0.0" "4317">
+      EnableSSL false
+      SSLCACertificateFile "/path/to/root.pem"
+      SSLCertificateFile "/path/to/client.pem"
+      SSLCertificateKeyFile "/path/to/client.key"
+      VerifyPeer false
+    </Receiver>
+    <Exporter "example">
+      Host "localhost"
+      Port "4317"
+    </Exporter>
+  </Plugin>
 
 =over 4
 
-=item B<Listen> I<Host> I<Port>
+=item B<Receiver> I<Host> I<Port>
 
-The B<Listen> statement sets the network address and port to which to bind.
-Multiple B<Listen> blocks can be specified to listen on multiple
-interfaces/ports. When no B<Listen> blocks are specified, it defaults to
-B<0.0.0.0:4317>.
+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
+interfaces/ports. When no B<Receiver> blocks are specified, the plugin will not
+receive any metrics.
 
 The argument I<Host> may be a hostname, an IPv4 address, or an IPv6 address.
 
-Optionally, B<Listen> blocks support the following options:
+Optionally, B<Receiver> blocks support the following options:
 
 =over 4
 
@@ -7195,6 +7212,24 @@ Enabled by default.
 
 =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<Port> I<Service>
+
+Service name or port number to connect to. Defaults to C<4317>.
+
+=back
+
 =back
 
 =head2 Plugin C<oracle>
@@ -11195,35 +11230,6 @@ want to use authentication all three fields must be set.
 
 =back
 
-=head2 Plugin C<write_open_telemetry>
-
-The I<write_open_telemetry plugin> will export metrics to an I<OpenTelemetry
-collector> using the gRPC based OTLP protocol.
-
-B<Synopsis:>
-
- <Plugin "write_open_telemetry">
-   <Node "default">
-     Host "localhost"
-     Port "4317"
-   </Node>
- </Plugin>
-
-The plugin can export metrics to multiple collectors by specifying multiple
-B<Node> blocks. Within the B<Node> 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<Port> I<Service>
-
-Service name or port number to connect to. Defaults to C<4317>.
-
-=back
-
 =head2 Plugin C<write_prometheus>
 
 The I<write_prometheus plugin> implements a tiny webserver that can be scraped
diff --git a/src/open_telemetry.cc b/src/open_telemetry.cc
new file mode 100644 (file)
index 0000000..f87ea92
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * collectd - src/open_telemetry.cc
+ * Copyright (C) 2024       Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Florian octo Forster <octo at collectd.org>
+ **/
+
+extern "C" {
+#include "collectd.h"
+
+#include "daemon/configfile.h"
+#include "daemon/plugin.h"
+}
+
+int exporter_config(oconfig_item_t *ci);
+int receiver_config(oconfig_item_t *ci);
+
+static int ot_config(oconfig_item_t *ci) {
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp("Exporter", child->key) == 0) {
+      int err = exporter_config(child);
+      if (err) {
+        ERROR("open_telemetry plugin: Configuring exporter failed "
+              "with status %d",
+              err);
+        return err;
+      }
+    } else if (strcasecmp("Receiver", child->key) == 0) {
+      int err = receiver_config(child);
+      if (err) {
+        ERROR("open_telemetry plugin: Configuring receiver failed "
+              "with status %d",
+              err);
+        return err;
+      }
+    } else {
+      ERROR("open_telemetry plugin: invalid config option: \"%s\"", child->key);
+      return EINVAL;
+    }
+  }
+
+  return 0;
+}
+
+extern "C" {
+void module_register(void) {
+  plugin_register_complex_config("open_telemetry", ot_config);
+}
+}
similarity index 91%
rename from src/write_open_telemetry.cc
rename to src/open_telemetry_exporter.cc
index 8491724c093e6f50be4652847937f24690694a7e..e382b8f10a8babd4d55a4ce93bad3025e7f22826 100644 (file)
@@ -1,6 +1,6 @@
 /**
- * collectd - src/write_open_telemetry.cc
- * Copyright (C) 2023       Florian octo Forster
+ * collectd - src/open_telemetry_exporter.cc
+ * Copyright (C) 2023-2024  Florian octo Forster
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -38,7 +38,7 @@
 extern "C" {
 #include "collectd.h"
 
-#include "plugin.h"
+#include "daemon/plugin.h"
 #include "utils/common/common.h"
 
 #include "utils/resource_metrics/resource_metrics.h"
@@ -196,7 +196,7 @@ static int ot_write(metric_family_t const *fam, user_data_t *user_data) {
   return 0;
 }
 
-static int ot_config_node(oconfig_item_t *ci) {
+int exporter_config(oconfig_item_t *ci) {
   ot_callback_t *cb = (ot_callback_t *)calloc(1, sizeof(*cb));
   if (cb == NULL) {
     ERROR("write_open_telemetry plugin: calloc failed.");
@@ -254,23 +254,3 @@ static int ot_config_node(oconfig_item_t *ci) {
   STRBUF_DESTROY(callback_name);
   return 0;
 }
-
-static int ot_config(oconfig_item_t *ci) {
-  for (int i = 0; i < ci->children_num; i++) {
-    oconfig_item_t *child = ci->children + i;
-
-    if (strcasecmp("Node", child->key) == 0)
-      ot_config_node(child);
-    else {
-      ERROR("write_open_telemetry plugin: Invalid configuration "
-            "option: %s.",
-            child->key);
-    }
-  }
-
-  return 0;
-}
-
-void module_register(void) {
-  plugin_register_complex_config("write_open_telemetry", ot_config);
-}
similarity index 94%
rename from src/open_telemetry_collector.cc
rename to src/open_telemetry_receiver.cc
index f70926e6153070f5e6662ee2ecbf9c941f79d56c..07d6dd498b90f32d50c913c9d8035df4509b8d58 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * collectd - src/grpc.cc
+ * collectd - src/open_telemetry_receiver.cc
  * Copyright (C) 2015-2016 Sebastian Harl
  * Copyright (C) 2016-2024 Florian octo Forster
  *
@@ -415,11 +415,50 @@ private:
 
 static CollectorServer *server = nullptr;
 
+static int receiver_init(void) {
+  if (server) {
+    return 0;
+  }
+
+  server = new CollectorServer();
+  if (!server) {
+    ERROR("open_telemetry_collector: Failed to create server");
+    return -1;
+  }
+
+  server->Start();
+  return 0;
+} /* receiver_init() */
+
+static int receiver_shutdown(void) {
+  if (!server)
+    return 0;
+
+  server->Shutdown();
+
+  delete server;
+  server = nullptr;
+
+  return 0;
+} /* receiver_shutdown() */
+
+static void receiver_install_callbacks(void) {
+  static bool done;
+
+  if (done) {
+    return;
+  }
+
+  plugin_register_init("open_telemetry_collector", receiver_init);
+  plugin_register_shutdown("open_telemetry_collector", receiver_shutdown);
+
+  done = true;
+}
+
 /*
  * collectd plugin interface
  */
-extern "C" {
-static int otelcol_config_listen(oconfig_item_t *ci) {
+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_collector: The `%s` config option needs exactly "
@@ -494,58 +533,6 @@ static int otelcol_config_listen(oconfig_item_t *ci) {
   }
 
   listeners.push_back(listener);
+  receiver_install_callbacks();
   return 0;
-} /* otelcol_config_listen() */
-
-static int otelcol_config(oconfig_item_t *ci) {
-  for (int i = 0; i < ci->children_num; i++) {
-    oconfig_item_t *child = ci->children + i;
-
-    if (!strcasecmp("Listen", child->key)) {
-      if (otelcol_config_listen(child)) {
-        return -1;
-      }
-    }
-
-    else {
-      WARNING("open_telemetry_collector: Option `%s` not allowed here.",
-              child->key);
-    }
-  }
-
-  return 0;
-} /* otelcol_config() */
-
-static int otelcol_init(void) {
-  if (server) {
-    return 0;
-  }
-
-  server = new CollectorServer();
-  if (!server) {
-    ERROR("open_telemetry_collector: Failed to create server");
-    return -1;
-  }
-
-  server->Start();
-  return 0;
-} /* otelcol_init() */
-
-static int otelcol_shutdown(void) {
-  if (!server)
-    return 0;
-
-  server->Shutdown();
-
-  delete server;
-  server = nullptr;
-
-  return 0;
-} /* otelcol_shutdown() */
-
-void module_register(void) {
-  plugin_register_complex_config("open_telemetry_collector", otelcol_config);
-  plugin_register_init("open_telemetry_collector", otelcol_init);
-  plugin_register_shutdown("open_telemetry_collector", otelcol_shutdown);
-} /* module_register() */
-} /* extern "C" */
+} /* receiver_config() */