Repository: envoyproxy/envoy
File: api/envoy/extensions/dynamic_modules/v3/dynamic_modules.proto (Protocol Buffers)

Code before:
  // The namespace prefix for metrics emitted by this dynamic module.
  //
  // This allows users to customize the prefix used for all metrics created by the dynamic module.
  // The prefix is prepended to all metric names.
  //
  // .. note::
  //   This prefix is stripped from the final output of ``/stats/prometheus`` endpoints unless
  //   ``include_metrics_namespace_in_stats_output`` is set to ``true``.
  //
  // Defaults to ``dynamicmodulescustom``.
  string metrics_namespace = 5;

  // If ``true``, the metrics namespace prefix is included in the ``/stats/prometheus`` output.
  //
  // By default, Envoy registers the ``metrics_namespace`` as a custom stat namespace, which causes
  // it to be stripped from prometheus output and the ``envoy_`` prefix is not added. This is
  // consistent with WASM behavior where user-defined metrics are treated differently from native
  // Envoy metrics.
  //
  // When set to ``true``, the namespace is not registered as a custom stat namespace, so metrics
  // will appear in prometheus output with the standard ``envoy_`` prefix followed by the namespace.
  // For example, if ``metrics_namespace`` is ``myapp``, a counter ``requests`` would appear as
  // ``envoy_myapp_requests`` instead of just ``requests``.
  //
  // Defaults to ``false``.
  bool include_metrics_namespace_in_stats_output = 6;
}


Review comment (suggestion):
For metrics system, my thought always be that the Envoy did too much. The collector could strip/replace the prefix rather the than customize it in the Envoy.

So, I actually prefer to change the default behavior with a runtime guard to always make Envoy output the full name envoy_myapp_requests for dynamic modules. And let the collector to take the duty to customize the name.


Code after:
syntax = "proto3";

package envoy.extensions.dynamic_modules.v3;

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.dynamic_modules.v3";
option java_outer_classname = "DynamicModulesProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/dynamic_modules/v3;dynamic_modulesv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Dynamic Modules Common Configuration]

// Configuration of a dynamic module. A dynamic module is a shared object file that can be loaded via
// ``dlopen`` by various Envoy extension points.
//
// How a module is loaded is determined by the extension point that uses it. For example, the HTTP
// filter loads the module when Envoy receives a configuration that references the module. If loading
// the module fails, the configuration will be rejected.
//
// A module is uniquely identified by its file path and the file's inode, depending on the platform.
// Notably, if the file path and the content of the file are the same, the shared object will be
// reused.
//
// A module must be compatible with the ABI specified in :repo:`abi.h
// <source/extensions/dynamic_modules/abi.h>`. Currently, compatibility is only guaranteed by an
// exact version match between the Envoy codebase and the dynamic module SDKs. In the future, after
// the ABI is stabilized, this restriction will be revisited. Until then, Envoy checks the hash of
// the ABI header files to ensure that the dynamic modules are built against the same version of the
// ABI.
// [#next-free-field: 6]
message DynamicModuleConfig {
  // The name of the dynamic module.
  //
  // The client is expected to have some configuration indicating where to search for the module. In
  // Envoy, the search path can be configured via the environment variable
  // ``ENVOY_DYNAMIC_MODULES_SEARCH_PATH``. The actual search path is
  // ``${ENVOY_DYNAMIC_MODULES_SEARCH_PATH}/lib${name}.so``. If not set, the current working directory is
  // used as the search path. After Envoy fails to find the module in the search path, it will also
  // try to find the module from a standard system library path (e.g., ``/usr/lib``) following the
  // platform's default behavior for ``dlopen``.
  //
  // .. note::
  //   There is some remaining work to make the search path configurable via command line options.
  string name = 1 [(validate.rules).string = {min_len: 1}];

  // If true, prevents the module from being unloaded with ``dlclose``.
  //
  // This is useful for modules that have global state that should not be unloaded. A module is
  // closed when no more references to it exist in the process. For example, no HTTP filters are
  // using the module (e.g. after configuration update).
  //
  // Defaults to ``false``.
  bool do_not_close = 3;

  // If ``true``, the dynamic module is loaded with the ``RTLD_GLOBAL`` flag.
  //
  // The dynamic module is loaded with the ``RTLD_LOCAL`` flag by default to avoid symbol conflicts
  // when multiple modules are loaded. Set this to ``true`` to load the module with the
  // ``RTLD_GLOBAL`` flag. This is useful for modules that need to share symbols with other dynamic
  // libraries. For example, a module X may load another shared library Y that depends on some
  // symbols defined in module X. In this case, module X must be loaded with the ``RTLD_GLOBAL``
  // flag so that the symbols defined in module X are visible to library Y.
  //
  // .. warning::
  //   Use this option with caution as it may lead to symbol conflicts and undefined behavior if
  //   multiple modules define the same symbols and are loaded globally.
  //
  // Defaults to ``false``.
  bool load_globally = 4;

  // The namespace prefix for metrics emitted by this dynamic module.
  //
  // This allows users to customize the prefix used for all metrics created by the dynamic module.
  // The prefix is prepended to all metric names. In prometheus output, metrics will appear with
  // the standard ``envoy_`` prefix followed by this namespace. For example, if this is set to
  // ``myapp``, a counter ``requests`` would appear as ``envoy_myapp_requests_total``.
  //
  // Defaults to ``dynamicmodulescustom``.
  string metrics_namespace = 5;
}