diff --git a/CHANGELOG.md b/CHANGELOG.md index 1198f72a..7e4c2137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to **DecaLog** are documented in this *changelog*. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and **DecaLog** adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.9.0] - 2023-10-25 + +### Added +- It's now possible to substitute environment variables for some loggers settings. +- Compatibility with WordPress 6.4. + +### Changed +- Settings options have been reorganized to be more consistent. ## [3.8.0] - 2023-07-19 diff --git a/admin/class-decalog-admin.php b/admin/class-decalog-admin.php index 77136db3..b73671e5 100644 --- a/admin/class-decalog-admin.php +++ b/admin/class-decalog-admin.php @@ -752,7 +752,6 @@ private function reset_listeners() { private function save_options() { if ( ! empty( $_POST ) ) { if ( array_key_exists( '_wpnonce', $_POST ) && wp_verify_nonce( $_POST['_wpnonce'], 'decalog-plugin-options' ) ) { - Option::network_set( 'metrics_authent', array_key_exists( 'decalog_plugin_options_metrics_authent', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_options_metrics_authent' ) : false ); Option::network_set( 'use_cdn', array_key_exists( 'decalog_plugin_options_usecdn', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_options_usecdn' ) : false ); Option::network_set( 'display_nag', array_key_exists( 'decalog_plugin_options_nag', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_options_nag' ) : false ); Option::network_set( 'adminbar', array_key_exists( 'decalog_plugin_options_adminbar', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_options_adminbar' ) : false ); @@ -761,10 +760,12 @@ private function save_options() { Option::network_set( 'logger_autostart', array_key_exists( 'decalog_loggers_options_autostart', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_autostart' ) : false ); Option::network_set( 'pseudonymization', array_key_exists( 'decalog_loggers_options_pseudonymization', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_pseudonymization' ) : false ); Option::network_set( 'respect_wp_debug', array_key_exists( 'decalog_loggers_options_wpdebug', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_wpdebug' ) : false ); + Option::network_set( 'env_substitution', array_key_exists( 'decalog_loggers_options_env_substitution', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_env_substitution' ) : false ); Option::network_set( 'privileges', array_key_exists( 'decalog_plugin_options_privileges', $_POST ) ? (string) filter_input( INPUT_POST, 'decalog_plugin_options_privileges', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'privileges' ) ); - Option::network_set( 'slow_query_warn', array_key_exists( 'decalog_loggers_options_slowqueries', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_slowqueries' ) : false ); - Option::network_set( 'unknown_metrics_warn', array_key_exists( 'decalog_loggers_options_unknownmetrics', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_unknownmetrics' ) : false ); - Option::network_set( 'trace_query', array_key_exists( 'decalog_loggers_options_tracequeries', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_loggers_options_tracequeries' ) : false ); + Option::network_set( 'metrics_authent', array_key_exists( 'decalog_plugin_features_metrics_authent', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_features_metrics_authent' ) : false ); + Option::network_set( 'slow_query_warn', array_key_exists( 'decalog_plugin_features_slowqueries', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_features_slowqueries' ) : false ); + Option::network_set( 'unknown_metrics_warn', array_key_exists( 'decalog_plugin_features_unknownmetrics', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_features_unknownmetrics' ) : false ); + Option::network_set( 'trace_query', array_key_exists( 'decalog_plugin_features_tracequeries', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_features_tracequeries' ) : false ); $autolog = array_key_exists( 'decalog_plugin_features_livelog', $_POST ) ? (bool) filter_input( INPUT_POST, 'decalog_plugin_features_livelog' ) : false; if ( $autolog ) { Autolog::activate(); @@ -1037,53 +1038,21 @@ public function loggers_options_section_callback() { ); register_setting( 'decalog_loggers_options_section', 'decalog_loggers_options_wpdebug' ); add_settings_field( - 'decalog_loggers_options_slowqueries', - __( 'Database', 'decalog' ), + 'decalog_loggers_options_env_substitution', + __( 'Parameters', 'decalog' ), [ $form, 'echo_field_checkbox' ], 'decalog_loggers_options_section', 'decalog_loggers_options_section', [ - 'text' => esc_html__( 'Warn about slow queries', 'decalog' ), - 'id' => 'decalog_loggers_options_slowqueries', - 'checked' => Option::network_get( 'slow_query_warn' ), - 'description' => sprintf( esc_html__( 'If checked, a warning will be triggered for each SQL query that takes %.1F ms or more to execute.', 'decalog' ), Option::network_get( 'slow_query_ms', 50 ) ), + 'text' => esc_html__( 'Environment variables substitution', 'decalog' ), + 'id' => 'decalog_loggers_options_env_substitution', + 'checked' => Option::network_get( 'env_substitution' ), + 'description' => esc_html__( 'If checked, DecaLog will replace strings between curly braces by the corresponding environment variables.', 'decalog' ), 'full_width' => false, 'enabled' => true, ] ); - register_setting( 'decalog_loggers_options_section', 'decalog_loggers_options_slowqueries' ); - add_settings_field( - 'decalog_loggers_options_tracequeries', - '', - [ $form, 'echo_field_checkbox' ], - 'decalog_loggers_options_section', - 'decalog_loggers_options_section', - [ - 'text' => esc_html__( 'Trace queries', 'decalog' ), - 'id' => 'decalog_loggers_options_tracequeries', - 'checked' => Option::network_get( 'trace_query' ), - 'description' => esc_html__( 'If checked, all SQL queries will be traced and pushed to running trace loggers.', 'decalog' ), - 'full_width' => false, - 'enabled' => true, - ] - ); - register_setting( 'decalog_loggers_options_section', 'decalog_loggers_options_tracequeries' ); - add_settings_field( - 'decalog_loggers_options_unknownmetrics', - __( 'Metrics', 'decalog' ), - [ $form, 'echo_field_checkbox' ], - 'decalog_loggers_options_section', - 'decalog_loggers_options_section', - [ - 'text' => esc_html__( 'Warn about non-existent metrics', 'decalog' ), - 'id' => 'decalog_loggers_options_unknownmetrics', - 'checked' => Option::network_get( 'unknown_metrics_warn' ), - 'description' => esc_html__( 'If checked, an error will be triggered when a process try to set a value for a metric which is not defined.', 'decalog' ), - 'full_width' => false, - 'enabled' => true, - ] - ); - register_setting( 'decalog_loggers_options_section', 'decalog_loggers_options_unknownmetrics' ); + register_setting( 'decalog_loggers_options_section', 'decalog_loggers_options_env_substitution' ); } /** @@ -1126,22 +1095,6 @@ public function plugin_options_section_callback() { ); register_setting( 'decalog_plugin_options_section', 'decalog_plugin_options_privileges' ); } - add_settings_field( - 'decalog_plugin_options_metrics_authent', - esc_html__( 'Metrics accesses', 'decalog' ), - [ $form, 'echo_field_checkbox' ], - 'decalog_plugin_options_section', - 'decalog_plugin_options_section', - [ - 'text' => esc_html__( 'Authenticated endpoint', 'decalog' ), - 'id' => 'decalog_plugin_options_metrics_authent', - 'checked' => Option::network_get( 'metrics_authent' ), - 'description' => sprintf( esc_html__( 'If checked, DecaLog will require authentication to serve %s calls.', 'decalog' ), '' . htmlentities( '/wp-json/' . DECALOG_REST_NAMESPACE . '/metrics' ) . '' ) . '
' . sprintf( esc_html__( 'Note: if you activate authentication, you must generate an application password for a user having %s capability.', 'decalog' ), 'read_private_pages' ), - 'full_width' => false, - 'enabled' => true, - ] - ); - register_setting( 'decalog_plugin_options_section', 'decalog_plugin_options_metrics_authent' ); add_settings_field( 'decalog_plugin_options_adminbar', __( 'Quick actions', 'decalog' ), @@ -1326,6 +1279,70 @@ public function plugin_features_section_callback() { ] ); register_setting( 'decalog_plugin_features_section', 'decalog_plugin_features_livelog' ); + add_settings_field( + 'decalog_plugin_features_slowqueries', + __( 'Database', 'decalog' ), + [ $form, 'echo_field_checkbox' ], + 'decalog_plugin_features_section', + 'decalog_plugin_features_section', + [ + 'text' => esc_html__( 'Warn about slow queries', 'decalog' ), + 'id' => 'decalog_plugin_features_slowqueries', + 'checked' => Option::network_get( 'slow_query_warn' ), + 'description' => sprintf( esc_html__( 'If checked, a warning will be triggered for each SQL query that takes %.1F ms or more to execute.', 'decalog' ), Option::network_get( 'slow_query_ms', 50 ) ), + 'full_width' => false, + 'enabled' => true, + ] + ); + register_setting( 'decalog_plugin_features_section', 'decalog_plugin_features_slowqueries' ); + add_settings_field( + 'decalog_plugin_features_tracequeries', + '', + [ $form, 'echo_field_checkbox' ], + 'decalog_plugin_features_section', + 'decalog_plugin_features_section', + [ + 'text' => esc_html__( 'Trace queries', 'decalog' ), + 'id' => 'decalog_plugin_features_tracequeries', + 'checked' => Option::network_get( 'trace_query' ), + 'description' => esc_html__( 'If checked, all SQL queries will be traced and pushed to running trace loggers.', 'decalog' ), + 'full_width' => false, + 'enabled' => true, + ] + ); + register_setting( 'decalog_plugin_features_section', 'decalog_plugin_features_tracequeries' ); + add_settings_field( + 'decalog_plugin_features_unknownmetrics', + __( 'Metrics', 'decalog' ), + [ $form, 'echo_field_checkbox' ], + 'decalog_plugin_features_section', + 'decalog_plugin_features_section', + [ + 'text' => esc_html__( 'Warn about non-existent metrics', 'decalog' ), + 'id' => 'decalog_plugin_features_unknownmetrics', + 'checked' => Option::network_get( 'unknown_metrics_warn' ), + 'description' => esc_html__( 'If checked, an error will be triggered when a process try to set a value for a metric which is not defined.', 'decalog' ), + 'full_width' => false, + 'enabled' => true, + ] + ); + register_setting( 'decalog_plugin_features_section', 'decalog_plugin_features_unknownmetrics' ); + add_settings_field( + 'decalog_plugin_features_metrics_authent', + '', + [ $form, 'echo_field_checkbox' ], + 'decalog_plugin_features_section', + 'decalog_plugin_features_section', + [ + 'text' => esc_html__( 'Authenticated endpoint', 'decalog' ), + 'id' => 'decalog_plugin_features_metrics_authent', + 'checked' => Option::network_get( 'metrics_authent' ), + 'description' => sprintf( esc_html__( 'If checked, DecaLog will require authentication to serve %s calls.', 'decalog' ), '' . htmlentities( '/wp-json/' . DECALOG_REST_NAMESPACE . '/metrics' ) . '' ) . '
' . sprintf( esc_html__( 'Note: if you activate authentication, you must generate an application password for a user having %s capability.', 'decalog' ), 'read_private_pages' ), + 'full_width' => false, + 'enabled' => true, + ] + ); + register_setting( 'decalog_plugin_features_section', 'decalog_plugin_features_metrics_authent' ); } } diff --git a/decalog.php b/decalog.php index de9b748c..3d9bb2c8 100644 --- a/decalog.php +++ b/decalog.php @@ -10,7 +10,7 @@ * Plugin Name: DecaLog * Plugin URI: https://perfops.one/decalog * Description: Capture and log events, metrics and traces on your site. Make WordPress observable – finally! - * Version: 3.8.0 + * Version: 3.9.0 * Requires at least: 5.2 * Requires PHP: 7.2 * Author: Pierre Lannoy / PerfOps One diff --git a/includes/features/class-handlertypes.php b/includes/features/class-handlertypes.php index e7af3018..87eddd63 100644 --- a/includes/features/class-handlertypes.php +++ b/includes/features/class-handlertypes.php @@ -11,6 +11,7 @@ namespace Decalog\Plugin\Feature; +use Decalog\System\Option; use DLMonolog\Logger; use Decalog\System\Cache; @@ -100,7 +101,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:8126', 'control' => [ 'type' => 'field_input_text', @@ -112,7 +113,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Custom tags', 'decalog' ), - 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ), + 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -186,7 +187,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:14268', 'control' => [ 'type' => 'field_input_text', @@ -199,7 +200,7 @@ public function __construct() { 'show' => true, 'name' => esc_html__( 'Service name', 'decalog' ), /* translators: "Jaeger thrift over HTTP" must not be translated because it is a "product name". */ - 'help' => esc_html__( 'Name of the service to use when "Jaeger thrift over HTTP" is the selected format.', 'decalog' ), + 'help' => esc_html__( 'Name of the service to use when "Jaeger thrift over HTTP" is the selected format.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'WordPress', 'control' => [ 'type' => 'field_input_text', @@ -211,7 +212,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Custom tags', 'decalog' ), - 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ), + 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -289,7 +290,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:9411', 'control' => [ 'type' => 'field_input_text', @@ -302,7 +303,7 @@ public function __construct() { 'show' => true, 'name' => esc_html__( 'Service name', 'decalog' ), /* translators: "Jaeger thrift over HTTP" must not be translated because it is a "product name". */ - 'help' => esc_html__( 'Name of the service to use when "Jaeger thrift over HTTP" is the selected format.', 'decalog' ), + 'help' => esc_html__( 'Name of the service to use when "Jaeger thrift over HTTP" is the selected format.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'WordPress', 'control' => [ 'type' => 'field_input_text', @@ -314,7 +315,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Custom tags', 'decalog' ), - 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ), + 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -391,7 +392,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:9411', 'control' => [ 'type' => 'field_input_text', @@ -404,7 +405,7 @@ public function __construct() { 'show' => true, 'name' => esc_html__( 'Service name', 'decalog' ), /* translators: "Jaeger thrift over HTTP" must not be translated because it is a "product name". */ - 'help' => esc_html__( 'Name of the service to use when "Jaeger thrift over HTTP" is the selected format.', 'decalog' ), + 'help' => esc_html__( 'Name of the service to use when "Jaeger thrift over HTTP" is the selected format.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'WordPress', 'control' => [ 'type' => 'field_input_text', @@ -416,7 +417,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Custom tags', 'decalog' ), - 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ), + 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -494,7 +495,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send spans. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:9411', 'control' => [ 'type' => 'field_input_text', @@ -506,7 +507,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Custom tags', 'decalog' ), - 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ), + 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -691,7 +692,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'II key', 'decalog' ), - 'help' => esc_html__( 'An account\'s "Insights insert key".', 'decalog' ), + 'help' => esc_html__( 'An account\'s "Insights insert key".', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -703,7 +704,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Custom tags', 'decalog' ), - 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ), + 'help' => sprintf( esc_html__( 'Custom tags to add to each span. Format: %s.', 'decalog' ), '' . htmlentities( 'key=value, key=value …' ) . '' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -806,7 +807,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'II key', 'decalog' ), - 'help' => esc_html__( 'An account\'s "Insights insert key".', 'decalog' ), + 'help' => esc_html__( 'An account\'s "Insights insert key".', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -911,7 +912,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'API key', 'decalog' ), - 'help' => esc_html__( 'The API key of the service.', 'decalog' ), + 'help' => esc_html__( 'The API key of the service.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1003,7 +1004,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send metrics. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send metrics. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:8086', 'control' => [ 'type' => 'field_input_text', @@ -1015,7 +1016,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Organization', 'decalog' ), - 'help' => esc_html__( 'Organization name to use (must exist).', 'decalog' ), + 'help' => esc_html__( 'Organization name to use (must exist).', 'decalog' ) . $this->get_substitution_note(), 'default' => 'my-org', 'control' => [ 'type' => 'field_input_text', @@ -1027,7 +1028,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Bucket', 'decalog' ), - 'help' => esc_html__( 'Bucket name to use (must exist).', 'decalog' ), + 'help' => esc_html__( 'Bucket name to use (must exist).', 'decalog' ) . $this->get_substitution_note(), 'default' => 'my-bucket', 'control' => [ 'type' => 'field_input_text', @@ -1039,7 +1040,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Token', 'decalog' ), - 'help' => esc_html__( 'Token value to write in bucket.', 'decalog' ), + 'help' => esc_html__( 'Token value to write in bucket.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'my-token', 'control' => [ 'type' => 'field_input_text', @@ -1211,7 +1212,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send metrics. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send metrics. Format: %s.', 'decalog' ), '' . htmlentities( '://[:]' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:9091', 'control' => [ 'type' => 'field_input_text', @@ -1236,7 +1237,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Job', 'decalog' ), - 'help' => esc_html__( 'The fixed job name for some templates.', 'decalog' ), + 'help' => esc_html__( 'The fixed job name for some templates.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'wp_decalog', 'control' => [ 'type' => 'field_input_text', @@ -1444,7 +1445,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'License key', 'decalog' ), - 'help' => esc_html__( 'The account\'s license key.', 'decalog' ), + 'help' => esc_html__( 'The account\'s license key.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1510,7 +1511,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'API key', 'decalog' ), - 'help' => esc_html__( 'The API key of the service.', 'decalog' ), + 'help' => esc_html__( 'The API key of the service.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1563,7 +1564,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Cloud ID', 'decalog' ), - 'help' => esc_html__( 'The generated cloud ID.', 'decalog' ), + 'help' => esc_html__( 'The generated cloud ID.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1575,7 +1576,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Username', 'decalog' ), - 'help' => esc_html__( 'The username of the instance.', 'decalog' ), + 'help' => esc_html__( 'The username of the instance.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1587,7 +1588,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Password', 'decalog' ), - 'help' => esc_html__( 'The password of the instance.', 'decalog' ), + 'help' => esc_html__( 'The password of the instance.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1599,7 +1600,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Index', 'decalog' ), - 'help' => esc_html__( 'The index name.', 'decalog' ), + 'help' => esc_html__( 'The index name.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'decalog', 'control' => [ 'type' => 'field_input_text', @@ -1648,7 +1649,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send logs. Format: %s.', 'decalog' ), '' . htmlentities( '://:' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send logs. Format: %s.', 'decalog' ), '' . htmlentities( '://:' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:9200', 'control' => [ 'type' => 'field_input_text', @@ -1660,7 +1661,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Username', 'decalog' ), - 'help' => esc_html__( 'The username of the instance.', 'decalog' ), + 'help' => esc_html__( 'The username of the instance.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1672,7 +1673,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Password', 'decalog' ), - 'help' => esc_html__( 'The password of the instance.', 'decalog' ), + 'help' => esc_html__( 'The password of the instance.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1684,7 +1685,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Index', 'decalog' ), - 'help' => esc_html__( 'The index name.', 'decalog' ), + 'help' => esc_html__( 'The index name.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'decalog', 'control' => [ 'type' => 'field_input_text', @@ -1733,7 +1734,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Connection string', 'decalog' ), - 'help' => esc_html__( 'Connection string to Fluentd. Can be something like "tcp://127.0.0.1:24224" or something like "unix:///var/run/td-agent/td-agent.sock".', 'decalog' ), + 'help' => esc_html__( 'Connection string to Fluentd. Can be something like "tcp://127.0.0.1:24224" or something like "unix:///var/run/td-agent/td-agent.sock".', 'decalog' ) . $this->get_substitution_note(), 'default' => 'tcp://localhost:24224', 'control' => [ 'type' => 'field_input_text', @@ -1780,7 +1781,7 @@ public function __construct() { 'class' => 'logging', 'minimal' => Logger::INFO, 'name' => 'Grafana Cloud Events', - 'help' => esc_html__( 'Events sent to Grafana Cloud.', 'decalog' ), + 'help' => esc_html__( 'Events sent to Grafana Cloud (Loki).', 'decalog' ), 'icon' => $this->get_base64_grafana_icon(), 'needs' => [], 'params' => [ 'processors', 'privacy' ], @@ -1789,7 +1790,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Loki host', 'decalog' ), - 'help' => sprintf( esc_html__( 'The host name portion of the Loki instance url. Something like %s.', 'decalog' ), 'logs-prod-us-central1' ), + 'help' => sprintf( esc_html__( 'The host name portion of the Loki instance url. Something like %s.', 'decalog' ), 'logs-prod-us-central1' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1801,7 +1802,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Username', 'decalog' ), - 'help' => sprintf( esc_html__( 'The user name for Basic Auth authentication. Something like %s.', 'decalog' ), '21087' ), + 'help' => sprintf( esc_html__( 'The user name for Basic Auth authentication. Something like %s.', 'decalog' ), '21087' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1813,7 +1814,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'API key', 'decalog' ), - 'help' => esc_html__( 'The Grafana.com API Key.', 'decalog' ), + 'help' => esc_html__( 'The Grafana.com API Key.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1838,7 +1839,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Job', 'decalog' ), - 'help' => esc_html__( 'The fixed job name for some templates.', 'decalog' ), + 'help' => esc_html__( 'The fixed job name for some templates.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'wp_decalog', 'control' => [ 'type' => 'field_input_text', @@ -1900,7 +1901,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Log token', 'decalog' ), - 'help' => esc_html__( 'The token of the Logentries/insightOps log.', 'decalog' ), + 'help' => esc_html__( 'The token of the Logentries/insightOps log.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1956,7 +1957,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Application token', 'decalog' ), - 'help' => esc_html__( 'The token of the Solawinds Loggly application.', 'decalog' ), + 'help' => esc_html__( 'The token of the Solawinds Loggly application.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -1989,7 +1990,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Service URL', 'decalog' ), - 'help' => sprintf( esc_html__( 'URL where to send logs. Format: %s.', 'decalog' ), '' . htmlentities( '://:' ) . '' ), + 'help' => sprintf( esc_html__( 'URL where to send logs. Format: %s.', 'decalog' ), '' . htmlentities( '://:' ) . '' ) . $this->get_substitution_note(), 'default' => 'http://localhost:3100', 'control' => [ 'type' => 'field_input_text', @@ -2014,7 +2015,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Job', 'decalog' ), - 'help' => esc_html__( 'The fixed job name for some templates.', 'decalog' ), + 'help' => esc_html__( 'The fixed job name for some templates.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'wp_decalog', 'control' => [ 'type' => 'field_input_text', @@ -2079,7 +2080,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'File', 'decalog' ), - 'help' => esc_html__( 'The full absolute path and filename, like "/path/to/file".', 'decalog' ), + 'help' => esc_html__( 'The full absolute path and filename, like "/path/to/file".', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -2152,7 +2153,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Application Token', 'decalog' ), - 'help' => esc_html__( 'The "Logs App Token" set in Sematext.', 'decalog' ), + 'help' => esc_html__( 'The "Logs App Token" set in Sematext.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'control' => [ 'type' => 'field_input_text', @@ -2193,7 +2194,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Connection string', 'decalog' ), - 'help' => esc_html__( 'Connection string to Fluentd. Can be something like "tcp://127.0.0.1:24224" or something like "unix:///var/run/td-agent/td-agent.sock".', 'decalog' ), + 'help' => esc_html__( 'Connection string to Fluentd. Can be something like "tcp://127.0.0.1:24224" or something like "unix:///var/run/td-agent/td-agent.sock".', 'decalog' ) . $this->get_substitution_note(), 'default' => 'tcp://localhost:24224', 'control' => [ 'type' => 'field_input_text', @@ -2262,7 +2263,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Source token', 'decalog' ), - 'help' => esc_html__( 'The token of cloud-syslog source.', 'decalog' ), + 'help' => esc_html__( 'The token of cloud-syslog source.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -2328,7 +2329,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Identifier', 'decalog' ), - 'help' => esc_html__( 'The program identifier for messages sent by DecaLog.', 'decalog' ), + 'help' => esc_html__( 'The program identifier for messages sent by DecaLog.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'DecaLog', 'control' => [ 'type' => 'field_input_text', @@ -2403,7 +2404,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Host', 'decalog' ), - 'help' => esc_html__( 'The remote host receiving syslog messages.', 'decalog' ), + 'help' => esc_html__( 'The remote host receiving syslog messages.', 'decalog' ) . $this->get_substitution_note(), 'default' => '127.0.0.1', 'control' => [ 'type' => 'field_input_text', @@ -2454,7 +2455,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Identifier', 'decalog' ), - 'help' => esc_html__( 'The program identifier for messages sent by DecaLog.', 'decalog' ), + 'help' => esc_html__( 'The program identifier for messages sent by DecaLog.', 'decalog' ) . $this->get_substitution_note(), 'default' => 'DecaLog', 'control' => [ 'type' => 'field_input_text', @@ -2801,7 +2802,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Recipients', 'decalog' ), - 'help' => esc_html__( 'The recipients mail address, in coma separated list.', 'decalog' ), + 'help' => esc_html__( 'The recipients mail address, in coma separated list.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -2875,7 +2876,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Application token', 'decalog' ), - 'help' => esc_html__( 'The token of the Pushover application.', 'decalog' ), + 'help' => esc_html__( 'The token of the Pushover application.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -2887,7 +2888,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Recipient', 'decalog' ), - 'help' => esc_html__( 'The recipient key. It can be a "user key" or a "group key".', 'decalog' ), + 'help' => esc_html__( 'The recipient key. It can be a "user key" or a "group key".', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -2899,7 +2900,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Message title', 'decalog' ), - 'help' => esc_html__( 'The title of the message which will be sent.', 'decalog' ), + 'help' => esc_html__( 'The title of the message which will be sent.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -2965,7 +2966,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'API key', 'decalog' ), - 'help' => esc_html__( 'The API key of the service.', 'decalog' ), + 'help' => esc_html__( 'The API key of the service.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -3018,7 +3019,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'Tracking ID', 'decalog' ), - 'help' => esc_html__( 'The tracking ID / web property ID for Google Universal Analytics service. The format must be UA-XXXX-Y.', 'decalog' ), + 'help' => esc_html__( 'The tracking ID / web property ID for Google Universal Analytics service. The format must be UA-XXXX-Y.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -3071,7 +3072,7 @@ public function __construct() { 'type' => 'string', 'show' => true, 'name' => esc_html__( 'API key', 'decalog' ), - 'help' => esc_html__( 'The API key of the service.', 'decalog' ), + 'help' => esc_html__( 'The API key of the service.', 'decalog' ) . $this->get_substitution_note(), 'default' => '', 'control' => [ 'type' => 'field_input_text', @@ -3146,6 +3147,19 @@ function ( $a, $b ) { ); } + /** + * Get the string for substitution note. + * + * @return string The string to add. + * @since 3.9.0 + */ + private function get_substitution_note() { + if ( ! Option::network_get( 'env_substitution' ) ) { + return ''; + } + return '
ⓘ ' . esc_html__( 'This field is eligible to environment variable substitution.', 'decalog' ) . ''; + } + /** * Get the types definition. * diff --git a/includes/features/class-loggerfactory.php b/includes/features/class-loggerfactory.php index 7e1f7a4b..4ab58b67 100644 --- a/includes/features/class-loggerfactory.php +++ b/includes/features/class-loggerfactory.php @@ -13,6 +13,7 @@ use Decalog\System\Option; use DLMonolog\Logger; +use function Automattic\Jetpack\Creative_Mail\error_notice; /** * Define the logger consistency functionality. @@ -49,6 +50,14 @@ class LoggerFactory { */ private $processor_types; + /** + * The substitutable configuration items. + * + * @since 3.9.0 + * @var array $substitutable The configuration items that could be substituted by environment variables. + */ + private $substitutable = [ 'url', 'ftags', 'service', 'host', 'token', 'org', 'bucket', 'id' , 'cloudid', 'user', 'pass', 'index', 'key', 'ident', 'recipients', 'users', 'title', 'filename' ]; + /** * Initialize the class and set its properties. * @@ -109,7 +118,20 @@ public function create_logger( $logger ) { $args[] = $p['value']; break; case 'configuration': - $args[] = $logger['configuration'][ $p['value'] ]; + $value = $logger['configuration'][ $p['value'] ]; + if ( Option::network_get( 'env_substitution' ) && is_string( $value ) /*&& in_array( $value, $this->substitutable )*/ ) { + if ( preg_match_all('/{(.*)}/U', $value,$matches ) ) { + if ( 2 === count( $matches ) ) { + foreach ($matches[1] as $match) { + $env = getenv( $match ); + if ( is_string( $env ) ) { + $value = str_replace( '{' . $match . '}', $env, $value ); + } + } + } + } + } + $args[] = $value; break; case 'compute': switch ( $p['value'] ) { diff --git a/includes/system/class-option.php b/includes/system/class-option.php index ed7d7ba1..8ff26f04 100644 --- a/includes/system/class-option.php +++ b/includes/system/class-option.php @@ -89,7 +89,8 @@ public static function init() { self::$defaults['trace_query'] = false; self::$defaults['slow_query_warn'] = true; self::$defaults['unknown_metrics_warn'] = true; - self::$network = [ 'version', 'earlyloading', 'use_cdn', 'download_favicons', 'script_in_footer', 'display_nag', 'respect_wp_debug', 'livelog', 'logger_autostart', 'autolisteners', 'pseudonymization', 'privileges', 'metrics_authent', 'adminbar', 'slow_query_ms', 'medium_query_ms', 'trace_query', 'slow_query_warn', 'unknown_metrics_warn' ]; + self::$defaults['env_substitution'] = false; + self::$network = [ 'version', 'earlyloading', 'use_cdn', 'download_favicons', 'script_in_footer', 'display_nag', 'respect_wp_debug', 'livelog', 'logger_autostart', 'autolisteners', 'pseudonymization', 'privileges', 'metrics_authent', 'adminbar', 'slow_query_ms', 'medium_query_ms', 'trace_query', 'slow_query_warn', 'unknown_metrics_warn', 'env_substitution' ]; } /** diff --git a/init.php b/init.php index 39d3d938..d58e01f0 100644 --- a/init.php +++ b/init.php @@ -12,7 +12,7 @@ define( 'DECALOG_PRODUCT_SHORTNAME', 'DecaLog' ); define( 'DECALOG_PRODUCT_ABBREVIATION', 'decalog' ); define( 'DECALOG_SLUG', 'decalog' ); -define( 'DECALOG_VERSION', '3.8.0' ); +define( 'DECALOG_VERSION', '3.9.0' ); define( 'DECALOG_API_VERSION', '3' ); define( 'DECALOG_MONOLOG_VERSION', '2.9.1' ); define( 'DECALOG_CODENAME', '"-"' ); diff --git a/readme.txt b/readme.txt index 6b85de20..96572d3a 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: logs, error reporting, monitoring, tracing, logging Requires at least: 5.2 Requires PHP: 7.2 Tested up to: 6.3 -Stable tag: 3.8.0 +Stable tag: 3.9.0 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html