You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by wk...@apache.org on 2022/04/25 23:37:35 UTC

[trafficserver] branch master updated: Reduce overhead incurred by enabling debug output. (#8581)

This is an automated email from the ASF dual-hosted git repository.

wkaras pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 1c038e512 Reduce overhead incurred by enabling debug output. (#8581)
1c038e512 is described below

commit 1c038e512103c4c1b32e335c980f9fae51f45f9d
Author: Walt Karas <wk...@verizonmedia.com>
AuthorDate: Mon Apr 25 18:37:30 2022 -0500

    Reduce overhead incurred by enabling debug output. (#8581)
    
    * Reduce overhead incurred by enabling debug output.
    
    Setting proxy.config.diags.debug.enabled to 3 enables most core debug output (whose tag matches the debug
    regex), and plugin debug output from the new API macro TSDbg().  Setting it to 1 enables all (matching) debug
    output, but with the previous high overhead.
    
    Note that enabling a large qualtity of debug output will still have a big impact on performance.
    
    This commit could be merge into proprietary branches of trafficserver, without causing routine
    merge conflicts when aligning with the open source branch.
    
    * Remove use __ in new code.
    
    Co-authored-by: Walt Karas <wk...@yahooinc.com>
---
 doc/admin-guide/files/records.config.en.rst        |   6 +-
 doc/developer-guide/api/functions/TSDebug.en.rst   |  21 ++-
 doc/developer-guide/debugging/debug-tags.en.rst    |  53 +++++-
 .../plugins/plugin-interfaces.en.rst               |  17 +-
 include/ts/apidefs.h.in                            |   5 +
 include/ts/ts.h                                    |  31 +++-
 include/tscore/DbgCtl.h                            |  56 ++++++
 include/tscore/Diags.h                             | 189 ++++++++++++++-------
 include/tscore/DiagsTypes.h                        |  51 +++++-
 include/tscore/LogMessage.h                        |   3 +-
 iocore/cache/test/main.cc                          |   8 +-
 iocore/hostdb/HostDB.cc                            |   2 +-
 iocore/net/P_UnixNetVConnection.h                  |   4 +-
 iocore/net/SSLDiags.cc                             |  38 +++--
 iocore/net/SSLDiags.h                              |  10 +-
 iocore/net/SSLUtils.cc                             |  22 ++-
 iocore/net/TLSSessionResumptionSupport.cc          |  11 +-
 iocore/net/quic/test/event_processor_main.cc       |   8 +-
 iocore/net/quic/test/main.cc                       |   8 +-
 iocore/net/test_certlookup.cc                      |   2 +-
 iocore/utils/diags.i                               |  28 ++-
 lib/records/test_I_RecLocal.cc                     |  15 +-
 lib/records/unit_tests/test_RecHttp.cc             |   2 +-
 lib/records/unit_tests/unit_test_main.cc           |   2 +-
 mgmt/RecordsConfig.cc                              |   2 +-
 mgmt/api/INKMgmtAPI.cc                             |   6 +-
 mgmt/api/include/mgmtapi.h                         |   6 +-
 mgmt/utils/MgmtUtils.cc                            |   6 +-
 proxy/hdrs/load_http_hdr.cc                        |   2 +-
 proxy/http/HttpTransact.h                          |   2 +-
 proxy/http3/test/main.cc                           |   8 +-
 proxy/http3/test/main_qpack.cc                     |   8 +-
 proxy/logging/LogStandalone.cc                     |   5 +-
 proxy/shared/DiagsConfig.cc                        |  24 +--
 src/traffic_crashlog/traffic_crashlog.cc           |  18 +-
 src/traffic_ctl/traffic_ctl.cc                     |  10 +-
 src/traffic_manager/traffic_manager.cc             |  28 +--
 src/traffic_quic/diags.h                           |  30 ++--
 src/traffic_server/InkAPI.cc                       |  33 +++-
 src/traffic_server/traffic_server.cc               |  30 ++--
 src/tscore/DbgCtl.cc                               | 111 ++++++++++++
 src/tscore/Diags.cc                                |  44 ++++-
 src/tscore/LogMessage.cc                           |  15 +-
 src/tscore/Makefile.am                             |   1 +
 src/tscore/ink_cap.cc                              |   6 +-
 .../unit_tests/test_X509HostnameValidator.cc       |   2 +-
 tests/gold_tests/pluginTest/tsapi/test_tsapi.cc    |  14 +-
 tests/gold_tests/pluginTest/tsapi/tsapi.test.py    |   2 +-
 48 files changed, 709 insertions(+), 296 deletions(-)

diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index af7f2a2a3..9da78bde0 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -3336,6 +3336,10 @@ Diagnostic Logging Configuration
 
    When set to 2, interprets the :ts:cv:`proxy.config.diags.debug.client_ip` setting determine whether diagnostic messages are logged.
 
+   When set to 3, enables logging for diagnostic messages whose log level is `diag` or `debug`, except those
+   output by deprecated functions such as `TSDebug()` and `TSDebugSpecific()`.  Using the value 3 will have less
+   of a negative impact on proxy throughput than using the value 1.
+
 .. ts:cv:: CONFIG proxy.config.diags.debug.client_ip STRING NULL
 
    if :ts:cv:`proxy.config.diags.debug.enabled` is set to 2, this value is tested against the source IP of the incoming connection.  If there is a match, all the diagnostic messages for that connection and the related outgoing connection will be logged.
@@ -3358,7 +3362,7 @@ Diagnostic Logging Configuration
    ssl           TLS termination and certificate processing
    ============  =====================================================
 
-   |TS| plugins will typically log debug messages using the :c:func:`TSDebug`
+   |TS| plugins will typically log debug messages using the :c:func:`TSDbg`
    API, passing the plugin name as the debug tag.
 
 .. ts:cv:: CONFIG proxy.config.diags.debug.throttling_interval_msec INT 0
diff --git a/doc/developer-guide/api/functions/TSDebug.en.rst b/doc/developer-guide/api/functions/TSDebug.en.rst
index f9cafdfc5..a12551001 100644
--- a/doc/developer-guide/api/functions/TSDebug.en.rst
+++ b/doc/developer-guide/api/functions/TSDebug.en.rst
@@ -18,8 +18,8 @@
 
 .. default-domain:: c
 
-TSDebug
-*******
+TSDbg
+*****
 
 Traffic Server Debugging APIs.
 
@@ -37,7 +37,11 @@ Synopsis
 .. function:: void TSFatal(const char * format, ...)
 .. function:: void TSAlert(const char * format, ...)
 .. function:: void TSEmergency(const char * format, ...)
+.. type:: TSDbgCtl
+.. function:: void TSDbg(const TSDbgCtl * ctlptr, const char * format, ...)
+.. function:: const TSDbgCtl * TSDbgCtlCreate(const char * tag)
 .. function:: void TSDebug(const char * tag, const char * format, ...)
+.. function:: int TSIsDbgCtlSet(const TSDbgCtl * ctlptr)
 .. function:: int TSIsDebugTagSet(const char * tag)
 .. function:: void TSDebugSpecific(int debug_flag, const char * tag, const char * format, ...)
 .. function:: void TSHttpTxnDebugSet(TSHttpTxn txnp, int on)
@@ -76,10 +80,19 @@ Traffic Server, Traffic Manager, AuTest, CI, and your log monitoring service/das
 trafficserver.out
 =================
 
-:func:`TSDebug` logs the debug message only if the given debug :arg:`tag` is enabled.
+:func:`TSDbg` logs the debug message only if the given debug control pointed to by
+:arg:`ctlptr` is enabled.  It writes output to the Traffic Server debug log through stderr.
+
+:func:`TSDbgCtlCreate` creates a debug control, associated with the
+debug :arg:`tag`, and returns a const pointer to it.
+
+:func:`TSIsDbgCtlSet` returns non-zero if the given debug control, pointed to by :arg:`ctlptr`, is
+enabled.
+
+:func:`TSDebug` (deprecated) logs the debug message only if the given debug :arg:`tag` is enabled.
 It writes output to the Traffic Server debug log through stderr.
 
-:func:`TSIsDebugTagSet` returns non-zero if the given debug :arg:`tag` is
+:func:`TSIsDebugTagSet` (deprecated) returns non-zero if the given debug :arg:`tag` is
 enabled.
 
 In debug mode, :macro:`TSAssert` Traffic Server to prints the file
diff --git a/doc/developer-guide/debugging/debug-tags.en.rst b/doc/developer-guide/debugging/debug-tags.en.rst
index 7738acebf..9cd45392d 100644
--- a/doc/developer-guide/debugging/debug-tags.en.rst
+++ b/doc/developer-guide/debugging/debug-tags.en.rst
@@ -22,16 +22,34 @@
 Debug Tags
 **********
 
-Use the API
-``void TSDebug (const char *tag, const char *format_str, ...)`` to add
-traces in your plugin. In this API:
+Use the API macro
+``TSDbg(ctlptr, const char *format_str, ...)`` to add
+traces in your plugin. In this macro:
+
+-  ``ctlptr`` is the Traffic Server parameter that enables Traffic Server
+   to print out ``format_str``.  It is returned by ``TSDbgCtlCreate()``.
+
+-  ``...`` are variables for ``format_str`` in the standard ``printf``
+   style.
+
+``void TSDbgCtlCreate (const char *tag)`` returns a (const) pointer to
+``TSDbgCtl``.  The ``TSDbgCtl`` control is enabled when debug output is
+enabled globally by configuaration, and ``tag`` matches a configured
+regular expression.
+
+The deprecated API
+``void TSDebug (const char *tag, const char *format_str, ...)`` also
+outputs traces.  In this API:
 
 -  ``tag`` is the Traffic Server parameter that enables Traffic Server
-   to print out *``format_str``*
+   to print out ``format_str``
 
--  ``...`` are variables for *``format_str``* in the standard ``printf``
+-  ``...`` are variables for ``format_str`` in the standard ``printf``
    style.
 
+Use of ``TSDebug()`` causes trace output to have a more negative impact
+on proxy throughput.
+
 Run Traffic Server with the ``-Ttag`` option. For example, if the tag is
 ``my-plugin``, then the debug output goes to ``traffic.out.``\ See
 below:
@@ -40,7 +58,7 @@ below:
 
        traffic_server -T"my-plugin"
 
-Set the following variables in :file:`records.config` (in the Traffic Server
+Sets the following variables in :file:`records.config` (in the Traffic Server
 ``config`` directory):
 
 ::
@@ -48,13 +66,22 @@ Set the following variables in :file:`records.config` (in the Traffic Server
        CONFIG proxy.config.diags.debug.enabled INT 1
        CONFIG proxy.config.diags.debug.tags STRING debug-tag-name
 
+(Performance will be better if ``enabled`` is set to 3 rather than 1, but,
+using 3, output from ``TSDebug()`` will not be enabled, only from ``TSDbg()``.)
 In this case, debug output goes to ``traffic.out``.
 
 Example:
 
 .. code-block:: c
 
-       TSDebug ("my-plugin", "Starting my-plugin at %d", the_time);
+       static TSDbgCtl const *my_dbg_ctl; // Non-local variable.
+       ...
+       my_dbg_ctl = TSDbgCtlCreate("my-plugin"); // In TSPluginInit() or TSRemapInit().
+       ...
+       TSDbg(my_dbg_ctl, "Starting my-plugin at %d", the_time);
+       ...
+       TSDbg(my_dbg_ctl, "Later on in my-plugin");
+
 
 The statement ``"Starting my-plugin at <time>"`` appears whenever you
 run Traffic Server with the ``my-plugin`` tag:
@@ -63,6 +90,16 @@ run Traffic Server with the ``my-plugin`` tag:
 
        traffic_server -T"my-plugin"
 
+If your plugin is a C++ plugin, the above example can be written as:
+
+.. code-block:: cpp
+
+       static auto my_dbg_ctl = TSDbgCtlCreate("my-plugin"); // Non-local variable.
+       ...
+       TSDbg(my_dbg_ctl, "Starting my-plugin at %d", the_time);
+       ...
+       TSDbg(my_dbg_ctl, "Later on in my-plugin");
+
 Other Useful Internal Debug Tags
 ================================
 
@@ -71,7 +108,7 @@ internal debugging purposes. These can also be used to follow Traffic
 Server behavior for testing and analysis.
 
 The debug tag setting (``-T`` and ``proxy.config.diags.debug.tags``) is a
-anchored regular expression against which the tag for a specific debug
+anchored regular expression (PCRE) against which the tag for a specific debug
 message is matched. This means the value "http" matches debug messages
 with the tag "http" but also "http\_seq" and "http\_trans". If you want
 multiple tags then use a pipe symbol to separate the tags. For example
diff --git a/doc/developer-guide/plugins/plugin-interfaces.en.rst b/doc/developer-guide/plugins/plugin-interfaces.en.rst
index 53c873b05..7011bf8c5 100644
--- a/doc/developer-guide/plugins/plugin-interfaces.en.rst
+++ b/doc/developer-guide/plugins/plugin-interfaces.en.rst
@@ -122,14 +122,15 @@ The thread functions are listed below:
 Debugging Functions
 ===================
 
--  :c:func:`TSDebug`
-   prints out a formatted statement if you are running Traffic Server in
-   debug mode.
-
--  :c:func:`TSIsDebugTagSet`
-   checks to see if a debug tag is set. If the debug tag is set, then
-   Traffic Server prints out all debug statements associated with the
-   tag.
+-  :c:func:`TSDbg`
+   (replaces deprecated :c:func:`TSDebug`) prints out a formatted
+   statement if you are running Traffic Server in debug mode.
+
+-  :c:func:`TSIsDbgCtlSet`
+   (replaces deprecated :c:func:`TSIsDebugTagSet`)
+   checks to see if a debug control (associated with a debug tag) is
+   set. If the debug tag is set, then Traffic Server prints out all
+   debug statements associated with the control.
 
 -  :c:func:`TSError`
    prints error messages to Traffic Server's error log
diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in
index 5dfc88fec..9baae2bfd 100644
--- a/include/ts/apidefs.h.in
+++ b/include/ts/apidefs.h.in
@@ -1071,6 +1071,11 @@ typedef struct TSHttpConnectOptions_s {
   TSIOBufferWaterMark buffer_water_mark;
 } TSHttpConnectOptions;
 
+typedef struct TSDbgCtl_s {
+  char volatile on; // Flag
+  char const *tag;
+} TSDbgCtl;
+
 /* --------------------------------------------------------------------------
    Init */
 
diff --git a/include/ts/ts.h b/include/ts/ts.h
index 4d35972e7..38f1160ca 100644
--- a/include/ts/ts.h
+++ b/include/ts/ts.h
@@ -2190,11 +2190,40 @@ tsapi void TSDebug(const char *tag, const char *format_str, ...) TS_PRINTFLIKE(2
     @param ... Format arguments.
  */
 tsapi void TSDebugSpecific(int debug_flag, const char *tag, const char *format_str, ...) TS_PRINTFLIKE(3, 4);
-extern int diags_on_for_plugins;
+extern int diags_on_for_plugins; /* Do not use directly. */
 #define TSDEBUG             \
   if (diags_on_for_plugins) \
   TSDebug
 
+extern char ts_new_debug_on_flag_; /* Do not use directly. */
+
+#define TSIsDbgCtlSet(ctlp__) (ts_new_debug_on_flag_ && ctlp__->on)
+
+/**
+    Output a debug line if the debug output control is turned on.
+
+    @param ctlp pointer to TSDbgCtl, returned by TSDbgCtlCreate().
+    @param ...  Format string and (optional) arguments.
+ */
+#define TSDbg(ctlp, ...)              \
+  do {                                \
+    if (TSIsDbgCtlSet(ctlp)) {        \
+      _TSDbg(ctlp->tag, __VA_ARGS__); \
+    }                                 \
+  } while (0)
+
+/**
+    Return a pointer for use with TSDbg().  For good performance,
+    this should be called in TSPluginInit() or TSRemapInit(), or in
+    static initialization in C++ (with the result stored in a
+    static pointer).
+
+    @param tag Debug tag for the control.
+ */
+tsapi TSDbgCtl const *TSDbgCtlCreate(char const *tag);
+
+void _TSDbg(const char *tag, const char *format_str, ...) TS_PRINTFLIKE(2, 3); /* Not for direct use. */
+
 /* --------------------------------------------------------------------------
    logging api */
 
diff --git a/include/tscore/DbgCtl.h b/include/tscore/DbgCtl.h
new file mode 100644
index 000000000..be5b7db4b
--- /dev/null
+++ b/include/tscore/DbgCtl.h
@@ -0,0 +1,56 @@
+/** @file
+
+  DbgCtl class header file.
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include <ts/ts.h>
+
+// For use with TSDbg().
+//
+class DbgCtl
+{
+public:
+  // Tag is a debug tag.  Debug output associated with this control will be output when debug output
+  // is enabled globally, and the tag matches the configured debug tag regular expression.
+  //
+  DbgCtl(char const *tag) : _ptr(_get_ptr(tag)) {}
+
+  TSDbgCtl const *
+  ptr() const
+  {
+    return _ptr;
+  }
+
+  // Call this when the compiled regex to enable tags may have changed.
+  //
+  static void update();
+
+private:
+  TSDbgCtl const *const _ptr;
+
+  static const TSDbgCtl *_get_ptr(char const *tag);
+
+  class _RegistryAccessor;
+
+  friend TSDbgCtl const *TSDbgCtlCreate(char const *tag);
+};
diff --git a/include/tscore/Diags.h b/include/tscore/Diags.h
index 53cfd759f..bab84d80b 100644
--- a/include/tscore/Diags.h
+++ b/include/tscore/Diags.h
@@ -56,17 +56,31 @@
 #endif
 #endif
 
-extern Diags *diags;
+class DiagsPtr
+{
+public:
+  friend Diags *diags();
+  static void set(Diags *new_ptr);
+
+private:
+  static Diags *_diags_ptr;
+};
+
+inline Diags *
+diags()
+{
+  return DiagsPtr::_diags_ptr;
+}
 
 // Note that the log functions being implemented as a macro has the advantage
 // that the pre-compiler expands this in place such that the call to
 // MakeSourceLocation happens at the call site for the function.
-#define DiagsError(level, ...)                              \
-  do {                                                      \
-    static const SourceLocation loc = MakeSourceLocation(); \
-    static LogMessage log_message;                          \
-    log_message.message(level, loc, __VA_ARGS__);           \
-  } while (0)
+#define DiagsError(LEVEL, ...)                                          \
+  do {                                                                  \
+    static const SourceLocation DiagsError_loc = MakeSourceLocation();  \
+    static LogMessage DiagsError_log_message;                           \
+    DiagsError_log_message.message(LEVEL, DiagsError_loc, __VA_ARGS__); \
+  } while (false)
 
 #define Status(...) DiagsError(DL_Status, __VA_ARGS__)       // Log information
 #define Note(...) DiagsError(DL_Note, __VA_ARGS__)           // Log significant information
@@ -87,12 +101,12 @@ extern Diags *diags;
  * present, but the set of possibly slightly different logs will still be
  * suppressed against a configurable interval as a whole.
  */
-#define SiteThrottledDiagsError(level, ...)                 \
-  do {                                                      \
-    static const SourceLocation loc = MakeSourceLocation(); \
-    static LogMessage log_message{IS_THROTTLED};            \
-    log_message.message(level, loc, __VA_ARGS__);           \
-  } while (0)
+#define SiteThrottledDiagsError(LEVEL, ...)                      \
+  do {                                                           \
+    static const SourceLocation STDE_loc = MakeSourceLocation(); \
+    static LogMessage STDE_log_message{IS_THROTTLED};            \
+    STDE_log_message.message(LEVEL, STDE_loc, __VA_ARGS__);      \
+  } while (false)
 
 #define SiteThrottledStatus(...) SiteThrottledDiagsError(DL_Status, __VA_ARGS__)   // Log information
 #define SiteThrottledNote(...) SiteThrottledDiagsError(DL_Note, __VA_ARGS__)       // Log significant information
@@ -105,12 +119,12 @@ extern Diags *diags;
 #define SiteThrottledEmergency(...) \
   SiteThrottledDiagsError(DL_Emergency, __VA_ARGS__) // Log unrecoverable crash, fail CI, exit, Ops attention
 
-#define DiagsErrorV(level, fmt, ap)                         \
-  do {                                                      \
-    static const SourceLocation loc = MakeSourceLocation(); \
-    static LogMessage log_message;                          \
-    log_message.message_va(level, loc, fmt, ap);            \
-  } while (0)
+#define DiagsErrorV(LEVEL, FMT, AP)                                      \
+  do {                                                                   \
+    static const SourceLocation DiagsErrorV_loc = MakeSourceLocation();  \
+    static LogMessage DiagsErrorV_log_message;                           \
+    DiagsErrorV_log_message.message_va(LEVEL, DiagsErrorV_loc, FMT, AP); \
+  } while (false)
 
 #define StatusV(fmt, ap) DiagsErrorV(DL_Status, fmt, ap)
 #define NoteV(fmt, ap) DiagsErrorV(DL_Note, fmt, ap)
@@ -122,12 +136,12 @@ extern Diags *diags;
 
 /** See the comment above SiteThrottledDiagsError for an explanation of how the
  * SiteThrottled functions behave. */
-#define SiteThrottledDiagsErrorV(level, fmt, ap)            \
-  do {                                                      \
-    static const SourceLocation loc = MakeSourceLocation(); \
-    static LogMessage log_message{IS_THROTTLED};            \
-    log_message.message_va(level, loc, fmt, ap);            \
-  } while (0)
+#define SiteThrottledDiagsErrorV(LEVEL, FMT, AP)                  \
+  do {                                                            \
+    static const SourceLocation STDEV_loc = MakeSourceLocation(); \
+    static LogMessage STDEV_log_message{IS_THROTTLED};            \
+    STDEV_log_message.message_va(LEVEL, STDEV_loc, FMT, AP);      \
+  } while (false)
 
 #define SiteThrottledStatusV(fmt, ap) SiteThrottledDiagsErrorV(DL_Status, fmt, ap)
 #define SiteThrottledNoteV(fmt, ap) SiteThrottledDiagsErrorV(DL_Note, fmt, ap)
@@ -140,52 +154,95 @@ extern Diags *diags;
 #if TS_USE_DIAGS
 
 /// A Diag version of the above.
-#define Diag(tag, ...)                                        \
-  do {                                                        \
-    if (unlikely(diags->on())) {                              \
-      static const SourceLocation loc = MakeSourceLocation(); \
-      static LogMessage log_message;                          \
-      log_message.diag(tag, loc, __VA_ARGS__);                \
-    }                                                         \
-  } while (0)
-
-/// A Debug version of the above.
-#define Debug(tag, ...)                                       \
-  do {                                                        \
-    if (unlikely(diags->on())) {                              \
-      static const SourceLocation loc = MakeSourceLocation(); \
-      static LogMessage log_message;                          \
-      log_message.debug(tag, loc, __VA_ARGS__);               \
-    }                                                         \
-  } while (0)
-
-/** Same as Debug above, but this allows a positive override of the tag
- * mechanism by a flag boolean.
- *
- * @param[in] flag True if the message should be logged regardless of tag
- * configuration, false if the logging of the message should respsect the tag
- * configuration.
- */
-#define SpecificDebug(flag, tag, ...)                                                                       \
-  do {                                                                                                      \
-    if (unlikely(diags->on())) {                                                                            \
-      static const SourceLocation loc = MakeSourceLocation();                                               \
-      static LogMessage log_message;                                                                        \
-      flag ? log_message.print(tag, DL_Debug, loc, __VA_ARGS__) : log_message.debug(tag, loc, __VA_ARGS__); \
-    }                                                                                                       \
-  } while (0)
-
-#define is_debug_tag_set(_t) unlikely(diags->on(_t, DiagsTagType_Debug))
-#define is_action_tag_set(_t) unlikely(diags->on(_t, DiagsTagType_Action))
+#define Diag(TAG, ...)                                             \
+  do {                                                             \
+    if (unlikely(diags()->on())) {                                 \
+      static const SourceLocation Diag_loc = MakeSourceLocation(); \
+      static LogMessage Diag_log_message;                          \
+      Diag_log_message.diag(TAG, Diag_loc, __VA_ARGS__);           \
+    }                                                              \
+  } while (false)
+
+inline bool
+is_dbg_ctl_enabled(DbgCtl const &ctl)
+{
+  return unlikely(diags()->on()) && ctl.ptr()->on;
+}
+
+// printf-line debug output.  First parameter must be DbgCtl instance. Assumes debug control is enabled, and
+// debug output globablly enabled.
+//
+#define DbgPrint(CTL, ...)                                                             \
+  do {                                                                                 \
+    static const SourceLocation DbgPrintf_loc = MakeSourceLocation();                  \
+    static LogMessage DbgPrintf_log_message;                                           \
+    DbgPrintf_log_message.print(CTL.ptr()->tag, DL_Debug, DbgPrintf_loc, __VA_ARGS__); \
+  } while (false)
+
+// printf-like debug output.  First parameter must be an instance of DbgCtl.
+//
+#define Dbg(CTL, ...)                               \
+  do {                                              \
+    if (unlikely(diags()->on()) && CTL.ptr()->on) { \
+      DbgPrint(CTL, __VA_ARGS__);                   \
+    }                                               \
+  } while (false)
+
+// printf-like debug output.  First parameter must be tag (C-string literal, or otherwise
+// a constexpr returning char const pointer to null-terminated C-string).
+//
+#define Debug(TAG, ...)                   \
+  do {                                    \
+    if (unlikely(diags()->on())) {        \
+      static DbgCtl Debug_ctl(TAG);       \
+      if (Debug_ctl.ptr()->on) {          \
+        DbgPrint(Debug_ctl, __VA_ARGS__); \
+      }                                   \
+    }                                     \
+  } while (false)
+
+// Same as Dbg above, but this allows a positive override of the DbgCtl, if flag is true.
+//
+#define SpecificDbg(FLAG, CTL, ...) \
+  do {                              \
+    if (unlikely(diags()->on())) {  \
+      if (FLAG || CTL.ptr()->on) {  \
+        DbgPrint(CTL, __VA_ARGS__); \
+      }                             \
+    }                               \
+  } while (false)
+
+// For better performance, use this instead of diags()->on(tag) when the tag parameter is a C-string literal.
+//
+#define is_debug_tag_set(TAG)                 \
+  (unlikely(diags()->on()) && ([]() -> bool { \
+     static DbgCtl idts_ctl(TAG);             \
+     return idts_ctl.ptr()->on != 0;          \
+   }()))
+
+#define SpecificDebug(FLAG, TAG, ...)               \
+  do {                                              \
+    {                                               \
+      static DbgCtl SpecificDebug_ctl(TAG);         \
+      if (unlikely(diags()->on())) {                \
+        if (FLAG || SpecificDebug_ctl.ptr()->on) {  \
+          DbgPrint(SpecificDebug_ctl, __VA_ARGS__); \
+        }                                           \
+      }                                             \
+    }                                               \
+  } while (false)
+
+#define is_action_tag_set(_t) unlikely(diags()->on(_t, DiagsTagType_Action))
 #define debug_tag_assert(_t, _a) (is_debug_tag_set(_t) ? (ink_release_assert(_a), 0) : 0)
 #define action_tag_assert(_t, _a) (is_action_tag_set(_t) ? (ink_release_assert(_a), 0) : 0)
-#define is_diags_on(_t) unlikely(diags->on(_t))
+#define is_diags_on(_t) is_debug_tag_set(_t) // Deprecated.
 
 #else // TS_USE_DIAGS
 
-#define Diag(tag, fmt, ...)
-#define Debug(tag, fmt, ...)
-#define SpecificDebug(flag, tag, ...)
+#define Diag(...)
+#define Dbg(...)
+#define Debug(...)
+#define SpecificDbg(...)
 
 #define is_debug_tag_set(_t) 0
 #define is_action_tag_set(_t) 0
diff --git a/include/tscore/DiagsTypes.h b/include/tscore/DiagsTypes.h
index 8e982426a..e1e8fd321 100644
--- a/include/tscore/DiagsTypes.h
+++ b/include/tscore/DiagsTypes.h
@@ -41,6 +41,7 @@
 #include "ink_mutex.h"
 #include "Regex.h"
 #include "SourceLocation.h"
+#include "DbgCtl.h"
 
 #define DIAGS_MAGIC 0x12345678
 #define BYTES_IN_MB 1000000
@@ -85,10 +86,21 @@ enum DiagsShowLocation { SHOW_LOCATION_NONE = 0, SHOW_LOCATION_DEBUG, SHOW_LOCAT
 //   cleanup process state
 typedef void (*DiagsCleanupFunc)();
 
-struct DiagsConfigState {
-  // this is static to eliminate many loads from the critical path
-  static int enabled[2];                     // one debug, one action
+class DiagsConfigState
+{
+public:
+  static int
+  enabled(DiagsTagType dtt)
+  {
+    return _enabled[dtt];
+  }
+
+  static void enabled(DiagsTagType dtt, int new_value);
+
   DiagsModeOutput outputs[DiagsLevel_Count]; // where each level prints
+
+private:
+  static int _enabled[2]; // one debug, one action
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -138,22 +150,51 @@ public:
     return this->debug_client_ip == test_ip;
   }
 
+  // It seems to make a big difference to performance (due to the caching of the enabled flag) to call this
+  // function first before doing anything else for debug output.  This includes entering blocks with static
+  // DbgCtl instances, or other static variables with non-const initialization.  Static variables with
+  // non-const initialization inside a function have a hidden flag that is checked every time the containing
+  // block is entered, to see if the variable has been initialized or not.
+  //
   bool
   on(DiagsTagType mode = DiagsTagType_Debug) const
   {
-    return ((config.enabled[mode] == 1) || (config.enabled[mode] == 2 && this->get_override()));
+    return (config.enabled(mode) & 1) || (config.enabled(mode) == 2 && this->get_override());
+  }
+
+  bool
+  on_for_TSDebug() const
+  {
+    return (config.enabled(DiagsTagType_Debug) == 1) || (config.enabled(DiagsTagType_Debug) == 2 && this->get_override());
   }
 
+  // is_debug_tag_set() is the faster alternative to this for debug mode, when the tag is a literal C-string
+  // (or otherwise is a constexpr returning char const *).
+  //
   bool
   on(const char *tag, DiagsTagType mode = DiagsTagType_Debug) const
   {
-    return this->on(mode) && tag_activated(tag, mode);
+    return unlikely(this->on(mode)) && tag_activated(tag, mode);
+  }
+
+  bool
+  on_for_TSDebug(const char *tag) const
+  {
+    return unlikely(this->on_for_TSDebug()) && tag_activated(tag, DiagsTagType_Debug);
+  }
+
+  bool
+  on(DbgCtl const &ctl) const
+  {
+    return unlikely(this->on(DiagsTagType_Debug)) && ctl.ptr()->on;
   }
 
   /////////////////////////////////////
   // low-level tag inquiry functions //
   /////////////////////////////////////
 
+  // This does regex match against the tag.
+  //
   bool tag_activated(const char *tag, DiagsTagType mode = DiagsTagType_Debug) const;
 
   /////////////////////////////
diff --git a/include/tscore/LogMessage.h b/include/tscore/LogMessage.h
index 141a7ecb6..487725894 100644
--- a/include/tscore/LogMessage.h
+++ b/include/tscore/LogMessage.h
@@ -61,7 +61,6 @@ public:
 
   /* TODO: Add BufferWriter overloads for these. */
   void diag(const char *tag, SourceLocation const &loc, const char *fmt, ...) TS_PRINTFLIKE(4, 5);
-  void debug(const char *tag, SourceLocation const &loc, const char *fmt, ...) TS_PRINTFLIKE(4, 5);
   void status(SourceLocation const &loc, const char *fmt, ...) TS_PRINTFLIKE(3, 4);
   void note(SourceLocation const &loc, const char *fmt, ...) TS_PRINTFLIKE(3, 4);
   void warning(SourceLocation const &loc, const char *fmt, ...) TS_PRINTFLIKE(3, 4);
@@ -123,7 +122,7 @@ private:
    */
   void message_debug_helper(const char *tag, DiagsLevel level, SourceLocation const &loc, const char *fmt, va_list args);
 
-  /** Same as above, but uses the tag-ignoring diags->print variant. */
+  /** Same as above, but uses the tag-ignoring diags()->print variant. */
   void message_print_helper(const char *tag, DiagsLevel level, SourceLocation const &loc, const char *fmt, va_list args);
 
 private:
diff --git a/iocore/cache/test/main.cc b/iocore/cache/test/main.cc
index 0e2379d3b..9151dee9b 100644
--- a/iocore/cache/test/main.cc
+++ b/iocore/cache/test/main.cc
@@ -66,10 +66,10 @@ struct EventProcessorListener : Catch::TestEventListenerBase {
   testRunStarting(Catch::TestRunInfo const &testRunInfo) override
   {
     BaseLogFile *base_log_file = new BaseLogFile("stderr");
-    diags                      = new Diags(testRunInfo.name, "*" /* tags */, "" /* actions */, base_log_file);
-    diags->activate_taglist("cache.*|agg.*|locks", DiagsTagType_Debug);
-    diags->config.enabled[DiagsTagType_Debug] = true;
-    diags->show_location                      = SHOW_LOCATION_DEBUG;
+    DiagsPtr::set(new Diags(testRunInfo.name, "*" /* tags */, "" /* actions */, base_log_file));
+    diags()->activate_taglist("cache.*|agg.*|locks", DiagsTagType_Debug);
+    diags()->config.enabled(DiagsTagType_Debug, 1);
+    diags()->show_location = SHOW_LOCATION_DEBUG;
 
     mime_init();
     Layout::create(temp_prefix());
diff --git a/iocore/hostdb/HostDB.cc b/iocore/hostdb/HostDB.cc
index 89968f6ca..01f88d9d2 100644
--- a/iocore/hostdb/HostDB.cc
+++ b/iocore/hostdb/HostDB.cc
@@ -1342,7 +1342,7 @@ HostDBContinuation::dnsEvent(int event, HostEnt *e)
       restore_info(r, old_r.get(), old_info, old_rr_data);
     }
     ink_assert(!r || !r->round_robin || !r->reverse_dns);
-    ink_assert(failed || !r->round_robin || r->app.rr.offset);
+    ink_assert(failed || ((r != nullptr) && (!r->round_robin || r->app.rr.offset)));
 
     if (!serve_stale) {
       hostDB.refcountcache->put(hash.hash.fold(), r, allocSize, r->expiry_time());
diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h
index 65e763f98..ae6859a3f 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -284,7 +284,7 @@ inline void
 UnixNetVConnection::set_remote_addr()
 {
   ats_ip_copy(&remote_addr, &con.addr);
-  this->control_flags.set_flag(ContFlags::DEBUG_OVERRIDE, diags->test_override_ip(remote_addr));
+  this->control_flags.set_flag(ContFlags::DEBUG_OVERRIDE, diags()->test_override_ip(remote_addr));
   set_cont_flags(get_control_flags());
 }
 
@@ -292,7 +292,7 @@ inline void
 UnixNetVConnection::set_remote_addr(const sockaddr *new_sa)
 {
   ats_ip_copy(&remote_addr, new_sa);
-  this->control_flags.set_flag(ContFlags::DEBUG_OVERRIDE, diags->test_override_ip(remote_addr));
+  this->control_flags.set_flag(ContFlags::DEBUG_OVERRIDE, diags()->test_override_ip(remote_addr));
   set_cont_flags(get_control_flags());
 }
 
diff --git a/iocore/net/SSLDiags.cc b/iocore/net/SSLDiags.cc
index 6a5e682c5..5f0874fbc 100644
--- a/iocore/net/SSLDiags.cc
+++ b/iocore/net/SSLDiags.cc
@@ -29,6 +29,8 @@
 #include "SSLStats.h"
 #include "P_SSLNetVConnection.h"
 
+static DbgCtl ssl_diags_dbg_ctl{"ssl-diag"};
+
 // return true if we have a stat for the error
 static bool
 increment_ssl_client_error(unsigned long err)
@@ -145,15 +147,15 @@ SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection *vc, cons
   while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
 #endif
     if (debug) {
-      if (unlikely(diags->on())) {
-        diags->log("ssl-diag", DL_Debug, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", es, ERR_error_string(l, buf), file, line,
-                   (flags & ERR_TXT_STRING) ? ":" : "", (flags & ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
-                   ip_buf);
+      if (diags()->on(ssl_diags_dbg_ctl)) {
+        diags()->print(ssl_diags_dbg_ctl.ptr()->tag, DL_Debug, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", es, ERR_error_string(l, buf),
+                       file, line, (flags & ERR_TXT_STRING) ? ":" : "", (flags & ERR_TXT_STRING) ? data : "",
+                       vc ? ": peer address is " : "", ip_buf);
       }
     } else {
-      diags->error(DL_Error, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", es, ERR_error_string(l, buf), file, line,
-                   (flags & ERR_TXT_STRING) ? ":" : "", (flags & ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
-                   ip_buf);
+      diags()->error(DL_Error, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", es, ERR_error_string(l, buf), file, line,
+                     (flags & ERR_TXT_STRING) ? ":" : "", (flags & ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
+                     ip_buf);
     }
 
     // Tally desired stats (only client/server connection stats, not init
@@ -170,9 +172,11 @@ SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection *vc, cons
 
   va_start(ap, fmt);
   if (debug) {
-    diags->log_va("ssl-diag", DL_Debug, &loc, fmt, ap);
+    if (diags()->on(ssl_diags_dbg_ctl)) {
+      diags()->print_va(ssl_diags_dbg_ctl.ptr()->tag, DL_Debug, &loc, fmt, ap);
+    }
   } else {
-    diags->error_va(DL_Error, &loc, fmt, ap);
+    diags()->error_va(DL_Error, &loc, fmt, ap);
   }
   va_end(ap);
 }
@@ -192,15 +196,13 @@ SSLErrorName(int ssl_error)
 }
 
 void
-SSLDebugBufferPrint(const char *tag, const char *buffer, unsigned buflen, const char *message)
+SSLDebugBufferPrint_(const char *buffer, unsigned buflen, const char *message)
 {
-  if (is_debug_tag_set(tag)) {
-    if (message != nullptr) {
-      fprintf(stdout, "%s\n", message);
-    }
-    for (unsigned ii = 0; ii < buflen; ii++) {
-      putc(buffer[ii], stdout);
-    }
-    putc('\n', stdout);
+  if (message != nullptr) {
+    fprintf(stdout, "%s\n", message);
+  }
+  for (unsigned ii = 0; ii < buflen; ii++) {
+    putc(buffer[ii], stdout);
   }
+  putc('\n', stdout);
 }
diff --git a/iocore/net/SSLDiags.h b/iocore/net/SSLDiags.h
index 52ccd0898..e0161d9ea 100644
--- a/iocore/net/SSLDiags.h
+++ b/iocore/net/SSLDiags.h
@@ -39,5 +39,11 @@ void SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection *vc,
 // Return a static string name for a SSL_ERROR constant.
 const char *SSLErrorName(int ssl_error);
 
-// Log a SSL network buffer.
-void SSLDebugBufferPrint(const char *tag, const char *buffer, unsigned buflen, const char *message);
+// Log a SSL network buffer.  TAG must be a C-string literal debug tag.
+#define SSLDebugBufferPrint(TAG, BUFFER, BUFFER_LEN, MESSAGE) \
+  do {                                                        \
+    if (is_debug_tag_set(TAG))                                \
+      SSLDebugBufferPrint_(BUFFER, BUFFER_LEN, MESSAGE);      \
+  } while (0)
+
+void SSLDebugBufferPrint_(const char *buffer, unsigned buflen, const char *message);
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 50492f5c7..9f2180505 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -205,11 +205,14 @@ ssl_new_cached_session(SSL *ssl, SSL_SESSION *sess)
 
   SSLSessionID sid(id, len);
 
-  if (diags->tag_activated("ssl.session_cache")) {
-    char printable_buf[(len * 2) + 1];
+  if (diags()->on()) {
+    static DbgCtl dbg_ctl("ssl.session_cache.insert");
+    if (dbg_ctl.ptr()->on) {
+      char printable_buf[(len * 2) + 1];
 
-    sid.toString(printable_buf, sizeof(printable_buf));
-    Debug("ssl.session_cache.insert", "ssl_new_cached_session session '%s' and context %p", printable_buf, SSL_get_SSL_CTX(ssl));
+      sid.toString(printable_buf, sizeof(printable_buf));
+      DbgPrint(dbg_ctl, "ssl_new_cached_session session '%s' and context %p", printable_buf, SSL_get_SSL_CTX(ssl));
+    }
   }
 
   SSL_INCREMENT_DYN_STAT(ssl_session_cache_new_session);
@@ -245,10 +248,13 @@ ssl_rm_cached_session(SSL_CTX *ctx, SSL_SESSION *sess)
     hook = hook->m_link.next;
   }
 
-  if (diags->tag_activated("ssl.session_cache")) {
-    char printable_buf[(len * 2) + 1];
-    sid.toString(printable_buf, sizeof(printable_buf));
-    Debug("ssl.session_cache.remove", "ssl_rm_cached_session cached session '%s'", printable_buf);
+  if (diags()->on()) {
+    static DbgCtl dbg_ctl("ssl.session_cache.remove");
+    if (dbg_ctl.ptr()->on) {
+      char printable_buf[(len * 2) + 1];
+      sid.toString(printable_buf, sizeof(printable_buf));
+      DbgPrint(dbg_ctl, "ssl_rm_cached_session cached session '%s'", printable_buf);
+    }
   }
 
   session_cache->removeSession(sid);
diff --git a/iocore/net/TLSSessionResumptionSupport.cc b/iocore/net/TLSSessionResumptionSupport.cc
index 9984b4731..6c2a827b3 100644
--- a/iocore/net/TLSSessionResumptionSupport.cc
+++ b/iocore/net/TLSSessionResumptionSupport.cc
@@ -140,10 +140,13 @@ TLSSessionResumptionSupport::getSession(SSL *ssl, const unsigned char *id, int l
   SSLSessionID sid(id, len);
 
   *copy = 0;
-  if (diags->tag_activated("ssl.session_cache")) {
-    char printable_buf[(len * 2) + 1];
-    sid.toString(printable_buf, sizeof(printable_buf));
-    Debug("ssl.session_cache.get", "ssl_get_cached_session cached session '%s' context %p", printable_buf, SSL_get_SSL_CTX(ssl));
+  if (diags()->on()) {
+    static DbgCtl dbg_ctl("ssl.session_cache.get");
+    if (dbg_ctl.ptr()->on) {
+      char printable_buf[(len * 2) + 1];
+      sid.toString(printable_buf, sizeof(printable_buf));
+      DbgPrint(dbg_ctl, "ssl_get_cached_session cached session '%s' context %p", printable_buf, SSL_get_SSL_CTX(ssl));
+    }
   }
 
   APIHook *hook = ssl_hooks->get(TSSslHookInternalID(TS_SSL_SESSION_HOOK));
diff --git a/iocore/net/quic/test/event_processor_main.cc b/iocore/net/quic/test/event_processor_main.cc
index 8963e9f2c..e430ac67f 100644
--- a/iocore/net/quic/test/event_processor_main.cc
+++ b/iocore/net/quic/test/event_processor_main.cc
@@ -43,10 +43,10 @@ struct EventProcessorListener : Catch::TestEventListenerBase {
   testRunStarting(Catch::TestRunInfo const &testRunInfo) override
   {
     BaseLogFile *base_log_file = new BaseLogFile("stderr");
-    diags                      = new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file);
-    diags->activate_taglist("vv_quic|quic", DiagsTagType_Debug);
-    diags->config.enabled[DiagsTagType_Debug] = true;
-    diags->show_location                      = SHOW_LOCATION_DEBUG;
+    DiagsPtr::set(new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file));
+    diags()->activate_taglist("vv_quic|quic", DiagsTagType_Debug);
+    diags()->config.enabled(DiagsTagType_Debug, 1);
+    diags()->show_location = SHOW_LOCATION_DEBUG;
 
     Layout::create();
     RecProcessInit(RECM_STAND_ALONE);
diff --git a/iocore/net/quic/test/main.cc b/iocore/net/quic/test/main.cc
index 4e7ee5adc..3eeb7cd30 100644
--- a/iocore/net/quic/test/main.cc
+++ b/iocore/net/quic/test/main.cc
@@ -40,10 +40,10 @@ struct EventProcessorListener : Catch::TestEventListenerBase {
   testRunStarting(Catch::TestRunInfo const &testRunInfo) override
   {
     BaseLogFile *base_log_file = new BaseLogFile("stderr");
-    diags                      = new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file);
-    diags->activate_taglist("vv_quic|quic", DiagsTagType_Debug);
-    diags->config.enabled[DiagsTagType_Debug] = true;
-    diags->show_location                      = SHOW_LOCATION_DEBUG;
+    DiagsPtr::set(new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file));
+    diags()->activate_taglist("vv_quic|quic", DiagsTagType_Debug);
+    diags()->config.enabled(DiagsTagType_Debug, 1);
+    diags()->show_location = SHOW_LOCATION_DEBUG;
 
     Layout::create();
     RecProcessInit(RECM_STAND_ALONE);
diff --git a/iocore/net/test_certlookup.cc b/iocore/net/test_certlookup.cc
index 0ffb580c9..fa1d793d2 100644
--- a/iocore/net/test_certlookup.cc
+++ b/iocore/net/test_certlookup.cc
@@ -210,7 +210,7 @@ int
 main(int argc, const char **argv)
 {
   BaseLogFile *blf = new BaseLogFile("stdout");
-  diags            = new Diags("test_certlookup", nullptr, nullptr, blf);
+  DiagsPtr::set(new Diags("test_certlookup", nullptr, nullptr, blf));
   res_track_memory = 1;
 
   SSL_library_init();
diff --git a/iocore/utils/diags.i b/iocore/utils/diags.i
index bb47f626b..60ee7b60a 100644
--- a/iocore/utils/diags.i
+++ b/iocore/utils/diags.i
@@ -41,13 +41,9 @@ reconfigure_diags()
   DiagsConfigState c;
 
 
-  // initial value set to 0 or 1 based on command line tags
-  c.enabled[DiagsTagType_Debug] = (diags->base_debug_tags != nullptr);
-  c.enabled[DiagsTagType_Action] = (diags->base_action_tags != nullptr);
-
-  c.enabled[DiagsTagType_Debug] = 1;
-  c.enabled[DiagsTagType_Action] = 1;
-  diags->show_location = SHOW_LOCATION_ALL;
+  c.enabled(DiagsTagType_Debug, 1);
+  c.enabled(DiagsTagType_Action, 1);
+  diags()->show_location = SHOW_LOCATION_ALL;
 
 
   // read output routing values
@@ -62,27 +58,27 @@ reconfigure_diags()
   // clear out old tag tables //
   //////////////////////////////
 
-  diags->deactivate_all(DiagsTagType_Debug);
-  diags->deactivate_all(DiagsTagType_Action);
+  diags()->deactivate_all(DiagsTagType_Debug);
+  diags()->deactivate_all(DiagsTagType_Action);
 
   //////////////////////////////////////////////////////////////////////
   //                     add new tag tables
   //////////////////////////////////////////////////////////////////////
 
-  if (diags->base_debug_tags) {
-    diags->activate_taglist(diags->base_debug_tags, DiagsTagType_Debug);
+  if (diags()->base_debug_tags) {
+    diags()->activate_taglist(diags()->base_debug_tags, DiagsTagType_Debug);
 }
-  if (diags->base_action_tags) {
-    diags->activate_taglist(diags->base_action_tags, DiagsTagType_Action);
+  if (diags()->base_action_tags) {
+    diags()->activate_taglist(diags()->base_action_tags, DiagsTagType_Action);
 }
 
 ////////////////////////////////////
 // change the diags config values //
 ////////////////////////////////////
 #if !defined(__GNUC__) && !defined(hpux)
-  diags->config = c;
+  diags()->config = c;
 #else
-  memcpy(((void *)&diags->config), ((void *)&c), sizeof(DiagsConfigState));
+  memcpy(((void *)&diags()->config), ((void *)&c), sizeof(DiagsConfigState));
 #endif
 }
 
@@ -93,7 +89,7 @@ init_diags(const char *bdt, const char *bat)
   char diags_logpath[500];
   strcpy(diags_logpath, DIAGS_LOG_FILE);
 
-  diags = new Diags("test", bdt, bat, new BaseLogFile(diags_logpath));
+  DiagsPtr::set(new Diags("test", bdt, bat, new BaseLogFile(diags_logpath)));
   Status("opened %s", diags_logpath);
 
   reconfigure_diags();
diff --git a/lib/records/test_I_RecLocal.cc b/lib/records/test_I_RecLocal.cc
index 9bc006b0d..056f1d1c1 100644
--- a/lib/records/test_I_RecLocal.cc
+++ b/lib/records/test_I_RecLocal.cc
@@ -27,7 +27,12 @@
 
 #include "P_RecCore.h"
 
-Diags *diags = nullptr;
+void
+DiagsPtr::set(Diags *new_ptr)
+{
+  _diags_ptr = new_ptr;
+}
+
 void RecDumpRecordsHt(RecT rec_type);
 
 //-------------------------------------------------------------------------
@@ -179,12 +184,12 @@ main(int argc, char **argv)
       log_fp = nullptr;
     }
   }
-  diags = new Diags("rec", nullptr, log_fp);
-  diags->activate_taglist(diags->base_debug_tags, DiagsTagType_Debug);
-  diags->log(nullptr, DTA(DL_Note), "Starting '%s'", argv[0]);
+  DiagsPtr::set(new Diags("rec", nullptr, log_fp));
+  diags()->activate_taglist(diags()->base_debug_tags, DiagsTagType_Debug);
+  diags()->log(nullptr, DTA(DL_Note), "Starting '%s'", argv[0]);
 
   // system initialization
-  RecLocalInit(diags);
+  RecLocalInit(diags());
   RecLocalInitMessage();
   RecordsConfigRegister();
   RecLocalStart();
diff --git a/lib/records/unit_tests/test_RecHttp.cc b/lib/records/unit_tests/test_RecHttp.cc
index cba93ebd9..a93b1e9b2 100644
--- a/lib/records/unit_tests/test_RecHttp.cc
+++ b/lib/records/unit_tests/test_RecHttp.cc
@@ -33,7 +33,7 @@ using ts::TextView;
 TEST_CASE("RecHttp", "[librecords][RecHttp]")
 {
   std::vector<HttpProxyPort> ports;
-  CatchDiags *cdiag = static_cast<CatchDiags *>(diags);
+  CatchDiags *cdiag = static_cast<CatchDiags *>(diags());
   cdiag->messages.clear();
 
   SECTION("base")
diff --git a/lib/records/unit_tests/unit_test_main.cc b/lib/records/unit_tests/unit_test_main.cc
index 8b236b73c..c5dbbb525 100644
--- a/lib/records/unit_tests/unit_test_main.cc
+++ b/lib/records/unit_tests/unit_test_main.cc
@@ -33,7 +33,7 @@ int
 main(int argc, char *argv[])
 {
   // Set the global diags variable
-  diags = new CatchDiags;
+  DiagsPtr::set(new CatchDiags);
 
   // Global data initialization needed for the unit tests.
   ts_session_protocol_well_known_name_indices_init();
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 091b0f4af..ee91dc9f2 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -194,7 +194,7 @@ static const RecordElement RecordsConfig[] =
   //#    L  diags.log
   //#
   //##############################################################################
-  {RECT_CONFIG, "proxy.config.diags.debug.enabled", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, "[0-1]", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.diags.debug.enabled", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, "[0-3]", RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.diags.debug.tags", RECD_STRING, "http|dns", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
   ,
diff --git a/mgmt/api/INKMgmtAPI.cc b/mgmt/api/INKMgmtAPI.cc
index d8a3347ac..3f4b9dde3 100644
--- a/mgmt/api/INKMgmtAPI.cc
+++ b/mgmt/api/INKMgmtAPI.cc
@@ -45,19 +45,19 @@
  * API Memory Management
  ***************************************************************************/
 void *
-_TSmalloc(unsigned int size, const char * /* path ATS_UNUSED */)
+_TSmalloc(size_t size, const char * /* path ATS_UNUSED */)
 {
   return ats_malloc(size);
 }
 
 void *
-_TSrealloc(void *ptr, unsigned int size, const char * /* path ATS_UNUSED */)
+_TSrealloc(void *ptr, size_t size, const char * /* path ATS_UNUSED */)
 {
   return ats_realloc(ptr, size);
 }
 
 char *
-_TSstrdup(const char *str, int length, const char * /* path ATS_UNUSED */)
+_TSstrdup(const char *str, int64_t length, const char * /* path ATS_UNUSED */)
 {
   return ats_strndup(str, length);
 }
diff --git a/mgmt/api/include/mgmtapi.h b/mgmt/api/include/mgmtapi.h
index dcc8cd722..38e85a6b0 100644
--- a/mgmt/api/include/mgmtapi.h
+++ b/mgmt/api/include/mgmtapi.h
@@ -234,9 +234,9 @@ typedef void (*TSDisconnectFunc)(void *data);
 #define TSstrndup(p, n) _TSstrdup((p), (n), TS_RES_MEM_PATH)
 #define TSfree(p) _TSfree(p)
 
-tsapi void *_TSmalloc(unsigned int size, const char *path);
-tsapi void *_TSrealloc(void *ptr, unsigned int size, const char *path);
-tsapi char *_TSstrdup(const char *str, int length, const char *path);
+tsapi void *_TSmalloc(size_t size, const char *path);
+tsapi void *_TSrealloc(void *ptr, size_t size, const char *path);
+tsapi char *_TSstrdup(const char *str, int64_t length, const char *path);
 tsapi void _TSfree(void *ptr);
 
 /***************************************************************************
diff --git a/mgmt/utils/MgmtUtils.cc b/mgmt/utils/MgmtUtils.cc
index 010fc7bca..c7eb7b572 100644
--- a/mgmt/utils/MgmtUtils.cc
+++ b/mgmt/utils/MgmtUtils.cc
@@ -228,7 +228,7 @@ mgmt_log(const char *message_format, ...)
   char extended_format[4096], message[4096];
 
   va_start(ap, message_format);
-  if (diags) {
+  if (diags()) {
     NoteV(message_format, ap);
   } else {
     if (use_syslog) {
@@ -254,7 +254,7 @@ mgmt_elog(const int lerrno, const char *message_format, ...)
 
   va_start(ap, message_format);
 
-  if (diags) {
+  if (diags()) {
     ErrorV(message_format, ap);
     if (lerrno != 0) {
       Error("last system error %d: %s", lerrno, strerror(lerrno));
@@ -288,7 +288,7 @@ mgmt_fatal(const int lerrno, const char *message_format, ...)
 
   va_start(ap, message_format);
 
-  if (diags) {
+  if (diags()) {
     if (lerrno != 0) {
       Error("last system error %d: %s", lerrno, strerror(lerrno));
     }
diff --git a/proxy/hdrs/load_http_hdr.cc b/proxy/hdrs/load_http_hdr.cc
index b4fe4e62e..0013fa8c0 100644
--- a/proxy/hdrs/load_http_hdr.cc
+++ b/proxy/hdrs/load_http_hdr.cc
@@ -297,7 +297,7 @@ main(int argc, const char *argv[])
   hdr_type h_type = UNKNOWN_HDR;
 
   http_init();
-  diags = new Diags(NULL, NULL);
+  DiagsPtr::set(new Diags(nullptr, nullptr));
   if (argc != 3) {
     fprintf(stderr, "Usage: %s req|res <file>\n", argv[0]);
     exit(1);
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index 2ec1e45af..7e7fc71ea 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -48,7 +48,7 @@
 
 #define DUMP_HEADER(T, H, I, S)                                 \
   {                                                             \
-    if (diags->on(T)) {                                         \
+    if (is_debug_tag_set(T)) {                                  \
       fprintf(stderr, "+++++++++ %s +++++++++\n", S);           \
       fprintf(stderr, "-- State Machine Id: %" PRId64 "\n", I); \
       char b[4096];                                             \
diff --git a/proxy/http3/test/main.cc b/proxy/http3/test/main.cc
index b0d4fa107..e9a7307e4 100644
--- a/proxy/http3/test/main.cc
+++ b/proxy/http3/test/main.cc
@@ -41,10 +41,10 @@ struct EventProcessorListener : Catch::TestEventListenerBase {
   testRunStarting(Catch::TestRunInfo const &testRunInfo) override
   {
     BaseLogFile *base_log_file = new BaseLogFile("stderr");
-    diags                      = new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file);
-    diags->activate_taglist("vv_quic|quic", DiagsTagType_Debug);
-    diags->config.enabled[DiagsTagType_Debug] = true;
-    diags->show_location                      = SHOW_LOCATION_DEBUG;
+    DiagsPtr::set(new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file));
+    diags()->activate_taglist("vv_quic|quic", DiagsTagType_Debug);
+    diags()->config.enabled(DiagsTagType_Debug, 1);
+    diags()->show_location = SHOW_LOCATION_DEBUG;
 
     Layout::create();
     RecProcessInit(RECM_STAND_ALONE);
diff --git a/proxy/http3/test/main_qpack.cc b/proxy/http3/test/main_qpack.cc
index 9bac453d0..999dad78d 100644
--- a/proxy/http3/test/main_qpack.cc
+++ b/proxy/http3/test/main_qpack.cc
@@ -56,10 +56,10 @@ struct EventProcessorListener : Catch::TestEventListenerBase {
   testRunStarting(Catch::TestRunInfo const &testRunInfo) override
   {
     BaseLogFile *base_log_file = new BaseLogFile("stderr");
-    diags                      = new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file);
-    diags->activate_taglist("qpack", DiagsTagType_Debug);
-    diags->config.enabled[DiagsTagType_Debug] = true;
-    diags->show_location                      = SHOW_LOCATION_DEBUG;
+    DiagsPtr::set(new Diags(testRunInfo.name, "" /* tags */, "" /* actions */, base_log_file));
+    diags()->activate_taglist("qpack", DiagsTagType_Debug);
+    diags()->config.enabled(DiagsTagType_Debug, 1);
+    diags()->show_location = SHOW_LOCATION_DEBUG;
 
     Layout::create();
     RecProcessInit(RECM_STAND_ALONE);
diff --git a/proxy/logging/LogStandalone.cc b/proxy/logging/LogStandalone.cc
index 620ea390e..f147cb5b5 100644
--- a/proxy/logging/LogStandalone.cc
+++ b/proxy/logging/LogStandalone.cc
@@ -60,7 +60,6 @@ char error_tags[1024]    = "";
 char action_tags[1024]   = "";
 char command_string[512] = "";
 
-// Diags *diags = NULL;
 DiagsConfig *diagsConfig      = nullptr;
 HttpBodyFactory *body_factory = nullptr;
 AppVersionInfo appVersionInfo;
@@ -104,9 +103,9 @@ initialize_process_manager()
   }
 
   // diags should have been initialized by caller, e.g.: sac.cc
-  ink_assert(diags);
+  ink_assert(diags());
 
-  RecProcessInit(remote_management_flag ? RECM_CLIENT : RECM_STAND_ALONE, diags);
+  RecProcessInit(remote_management_flag ? RECM_CLIENT : RECM_STAND_ALONE, diags());
   LibRecordsConfigInit();
 
   // Start up manager
diff --git a/proxy/shared/DiagsConfig.cc b/proxy/shared/DiagsConfig.cc
index 7b50ebde2..08afcbffa 100644
--- a/proxy/shared/DiagsConfig.cc
+++ b/proxy/shared/DiagsConfig.cc
@@ -67,20 +67,20 @@ DiagsConfig::reconfigure_diags()
   all_found = true;
 
   // initial value set to 0 or 1 based on command line tags
-  c.enabled[DiagsTagType_Debug]  = (_diags->base_debug_tags != nullptr);
-  c.enabled[DiagsTagType_Action] = (_diags->base_action_tags != nullptr);
+  c.enabled(DiagsTagType_Debug, _diags->base_debug_tags != nullptr ? 1 : 0);
+  c.enabled(DiagsTagType_Action, _diags->base_action_tags != nullptr ? 1 : 0);
 
   // enabled if records.config set
 
   e = static_cast<int>(REC_readInteger("proxy.config.diags.debug.enabled", &found));
   if (e && found) {
-    c.enabled[DiagsTagType_Debug] = e; // implement OR logic
+    c.enabled(DiagsTagType_Debug, e); // implement OR logic
   }
   all_found = all_found && found;
 
   e = static_cast<int>(REC_readInteger("proxy.config.diags.action.enabled", &found));
   if (e && found) {
-    c.enabled[DiagsTagType_Action] = true; // implement OR logic
+    c.enabled(DiagsTagType_Action, 1); // implement OR logic
   }
   all_found = all_found && found;
 
@@ -172,7 +172,7 @@ diags_config_callback(const char * /* name ATS_UNUSED */, RecDataT /* data_type
   DiagsConfig *diagsConfig;
 
   diagsConfig = static_cast<DiagsConfig *>(opaque_token);
-  ink_assert(::diags->magic == DIAGS_MAGIC);
+  ink_assert(::diags()->magic == DIAGS_MAGIC);
   diagsConfig->reconfigure_diags();
   return (0);
 }
@@ -226,16 +226,16 @@ DiagsConfig::config_diags_norecords()
 
   if (_diags->base_debug_tags) {
     _diags->activate_taglist(_diags->base_debug_tags, DiagsTagType_Debug);
-    c.enabled[DiagsTagType_Debug] = true;
+    c.enabled(DiagsTagType_Debug, 1);
   } else {
-    c.enabled[DiagsTagType_Debug] = false;
+    c.enabled(DiagsTagType_Debug, 0);
   }
 
   if (_diags->base_action_tags) {
     _diags->activate_taglist(_diags->base_action_tags, DiagsTagType_Action);
-    c.enabled[DiagsTagType_Action] = true;
+    c.enabled(DiagsTagType_Action, 1);
   } else {
-    c.enabled[DiagsTagType_Action] = false;
+    c.enabled(DiagsTagType_Action, 0);
   }
 
 #if !defined(__GNUC__)
@@ -258,8 +258,8 @@ DiagsConfig::DiagsConfig(std::string_view prefix_string, const char *filename, c
   ////////////////////////////////////////////////////////////////////
 
   if (!use_records) {
-    _diags  = new Diags(prefix_string, tags, actions, nullptr);
-    ::diags = _diags;
+    _diags = new Diags(prefix_string, tags, actions, nullptr);
+    DiagsPtr::set(_diags);
     config_diags_norecords();
     return;
   }
@@ -306,7 +306,7 @@ DiagsConfig::DiagsConfig(std::string_view prefix_string, const char *filename, c
   // Set up diags, FILE streams are opened in Diags constructor
   diags_log = new BaseLogFile(diags_logpath.c_str());
   _diags    = new Diags(prefix_string, tags, actions, diags_log, diags_perm_parsed, output_perm_parsed);
-  ::diags   = _diags;
+  DiagsPtr::set(_diags);
   _diags->config_roll_diagslog(static_cast<RollingEnabledValues>(diags_log_roll_enable), diags_log_roll_int, diags_log_roll_size);
   _diags->config_roll_outputlog(static_cast<RollingEnabledValues>(output_log_roll_enable), output_log_roll_int,
                                 output_log_roll_size);
diff --git a/src/traffic_crashlog/traffic_crashlog.cc b/src/traffic_crashlog/traffic_crashlog.cc
index 936ccefda..6828293da 100644
--- a/src/traffic_crashlog/traffic_crashlog.cc
+++ b/src/traffic_crashlog/traffic_crashlog.cc
@@ -138,7 +138,7 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   crashlog_target target;
   pid_t parent = getppid();
 
-  diags = new Diags("traffic_crashlog", "" /* tags */, "" /* actions */, new BaseLogFile("stderr"));
+  DiagsPtr::set(new Diags("traffic_crashlog", "" /* tags */, "" /* actions */, new BaseLogFile("stderr")));
 
   appVersionInfo.setup(PACKAGE_NAME, "traffic_crashlog", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
@@ -182,14 +182,14 @@ main(int /* argc ATS_UNUSED */, const char **argv)
     }
 
     openlog(appVersionInfo.AppStr, LOG_PID | LOG_NDELAY | LOG_NOWAIT, facility);
-    diags->config.outputs[DL_Debug].to_syslog     = true;
-    diags->config.outputs[DL_Status].to_syslog    = true;
-    diags->config.outputs[DL_Note].to_syslog      = true;
-    diags->config.outputs[DL_Warning].to_syslog   = true;
-    diags->config.outputs[DL_Error].to_syslog     = true;
-    diags->config.outputs[DL_Fatal].to_syslog     = true;
-    diags->config.outputs[DL_Alert].to_syslog     = true;
-    diags->config.outputs[DL_Emergency].to_syslog = true;
+    diags()->config.outputs[DL_Debug].to_syslog     = true;
+    diags()->config.outputs[DL_Status].to_syslog    = true;
+    diags()->config.outputs[DL_Note].to_syslog      = true;
+    diags()->config.outputs[DL_Warning].to_syslog   = true;
+    diags()->config.outputs[DL_Error].to_syslog     = true;
+    diags()->config.outputs[DL_Fatal].to_syslog     = true;
+    diags()->config.outputs[DL_Alert].to_syslog     = true;
+    diags()->config.outputs[DL_Emergency].to_syslog = true;
   }
 
   Note("crashlog started, target=%ld, debug=%s syslog=%s, uid=%ld euid=%ld", static_cast<long>(target_pid),
diff --git a/src/traffic_ctl/traffic_ctl.cc b/src/traffic_ctl/traffic_ctl.cc
index f7d570e21..6c6ef2be6 100644
--- a/src/traffic_ctl/traffic_ctl.cc
+++ b/src/traffic_ctl/traffic_ctl.cc
@@ -267,12 +267,12 @@ main(int argc, const char **argv)
   engine.arguments = engine.parser.parse(argv);
 
   BaseLogFile *base_log_file = new BaseLogFile("stderr");
-  diags                      = new Diags("traffic_ctl", "" /* tags */, "" /* actions */, base_log_file);
+  DiagsPtr::set(new Diags("traffic_ctl", "" /* tags */, "" /* actions */, base_log_file));
 
   if (engine.arguments.get("debug")) {
-    diags->activate_taglist("traffic_ctl", DiagsTagType_Debug);
-    diags->config.enabled[DiagsTagType_Debug] = true;
-    diags->show_location                      = SHOW_LOCATION_DEBUG;
+    diags()->activate_taglist("traffic_ctl", DiagsTagType_Debug);
+    diags()->config.enabled(DiagsTagType_Debug, 1);
+    diags()->show_location = SHOW_LOCATION_DEBUG;
   }
 
   argparser_runroot_handler(engine.arguments.get("run-root").value(), argv[0]);
@@ -280,7 +280,7 @@ main(int argc, const char **argv)
 
   // This is a little bit of a hack, for now it'll suffice.
   max_records_entries = 262144;
-  RecProcessInit(RECM_STAND_ALONE, diags);
+  RecProcessInit(RECM_STAND_ALONE, diags());
   LibRecordsConfigInit();
 
   ats_scoped_str rundir(RecConfigReadRuntimeDir());
diff --git a/src/traffic_manager/traffic_manager.cc b/src/traffic_manager/traffic_manager.cc
index 5123e6b2a..f04c3df03 100644
--- a/src/traffic_manager/traffic_manager.cc
+++ b/src/traffic_manager/traffic_manager.cc
@@ -128,15 +128,15 @@ rotateLogs()
   int diags_log_roll_int     = (int)REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_interval_sec");
   int diags_log_roll_size    = (int)REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_size_mb");
   int diags_log_roll_enable  = (int)REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_enabled");
-  diags->config_roll_diagslog((RollingEnabledValues)diags_log_roll_enable, diags_log_roll_int, diags_log_roll_size);
-  diags->config_roll_outputlog((RollingEnabledValues)output_log_roll_enable, output_log_roll_int, output_log_roll_size);
+  diags()->config_roll_diagslog((RollingEnabledValues)diags_log_roll_enable, diags_log_roll_int, diags_log_roll_size);
+  diags()->config_roll_outputlog((RollingEnabledValues)output_log_roll_enable, output_log_roll_int, output_log_roll_size);
 
   // Now we can actually roll the logs (if necessary)
-  if (diags->should_roll_diagslog()) {
+  if (diags()->should_roll_diagslog()) {
     mgmt_log("Rotated %s", diags_log_filename);
   }
 
-  if (diags->should_roll_outputlog()) {
+  if (diags()->should_roll_outputlog()) {
     // send a signal to TS to reload traffic.out, so the logfile is kept
     // synced across processes
     mgmt_log("Sending SIGUSR2 to TS");
@@ -552,8 +552,8 @@ main(int argc, const char **argv)
   // Bootstrap the Diags facility so that we can use it while starting
   //  up the manager
   diagsConfig = new DiagsConfig("Manager", DEFAULT_DIAGS_LOG_FILENAME, debug_tags, action_tags, false);
-  diags->set_std_output(StdStream::STDOUT, bind_stdout);
-  diags->set_std_output(StdStream::STDERR, bind_stderr);
+  diags()->set_std_output(StdStream::STDOUT, bind_stdout);
+  diags()->set_std_output(StdStream::STDERR, bind_stderr);
 
   RecLocalInit();
   LibRecordsConfigInit();
@@ -608,14 +608,14 @@ main(int argc, const char **argv)
     old_diagsconfig = nullptr;
   }
 
-  RecSetDiags(diags);
-  diags->set_std_output(StdStream::STDOUT, bind_stdout);
-  diags->set_std_output(StdStream::STDERR, bind_stderr);
+  RecSetDiags(diags());
+  diags()->set_std_output(StdStream::STDOUT, bind_stdout);
+  diags()->set_std_output(StdStream::STDERR, bind_stderr);
 
   if (is_debug_tag_set("diags")) {
-    diags->dump();
+    diags()->dump();
   }
-  diags->cleanup_func = mgmt_cleanup;
+  diags()->cleanup_func = mgmt_cleanup;
 
   // Setup the exported manager version records.
   RecSetRecordString("proxy.node.version.manager.short", appVersionInfo.VersionStr, REC_SOURCE_DEFAULT);
@@ -944,9 +944,9 @@ SignalHandler(int sig)
     if (lmgmt && lmgmt->watched_process_pid != -1) {
       kill(lmgmt->watched_process_pid, sig);
     }
-    diags->set_std_output(StdStream::STDOUT, bind_stdout);
-    diags->set_std_output(StdStream::STDERR, bind_stderr);
-    if (diags->reseat_diagslog()) {
+    diags()->set_std_output(StdStream::STDOUT, bind_stdout);
+    diags()->set_std_output(StdStream::STDERR, bind_stderr);
+    if (diags()->reseat_diagslog()) {
       Note("Reseated %s", diags_log_filename);
     } else {
       Note("Could not reseat %s", diags_log_filename);
diff --git a/src/traffic_quic/diags.h b/src/traffic_quic/diags.h
index 031d6b54a..42a9b56c8 100644
--- a/src/traffic_quic/diags.h
+++ b/src/traffic_quic/diags.h
@@ -34,13 +34,9 @@ reconfigure_diags()
   int i;
   DiagsConfigState c;
 
-  // initial value set to 0 or 1 based on command line tags
-  c.enabled[DiagsTagType_Debug]  = (diags->base_debug_tags != nullptr);
-  c.enabled[DiagsTagType_Action] = (diags->base_action_tags != nullptr);
-
-  c.enabled[DiagsTagType_Debug]  = 1;
-  c.enabled[DiagsTagType_Action] = 1;
-  diags->show_location           = SHOW_LOCATION_ALL;
+  c.enabled(DiagsTagType_Debug, 1);
+  c.enabled(DiagsTagType_Action, 1);
+  diags()->show_location = SHOW_LOCATION_ALL;
 
   // read output routing values
   for (i = 0; i < DL_Status; i++) {
@@ -61,25 +57,27 @@ reconfigure_diags()
   // clear out old tag tables //
   //////////////////////////////
 
-  diags->deactivate_all(DiagsTagType_Debug);
-  diags->deactivate_all(DiagsTagType_Action);
+  diags()->deactivate_all(DiagsTagType_Debug);
+  diags()->deactivate_all(DiagsTagType_Action);
 
   //////////////////////////////////////////////////////////////////////
   //                     add new tag tables
   //////////////////////////////////////////////////////////////////////
 
-  if (diags->base_debug_tags)
-    diags->activate_taglist(diags->base_debug_tags, DiagsTagType_Debug);
-  if (diags->base_action_tags)
-    diags->activate_taglist(diags->base_action_tags, DiagsTagType_Action);
+  if (diags()->base_debug_tags) {
+    diags()->activate_taglist(diags()->base_debug_tags, DiagsTagType_Debug);
+  }
+  if (diags()->base_action_tags) {
+    diags()->activate_taglist(diags()->base_action_tags, DiagsTagType_Action);
+  }
 
 ////////////////////////////////////
 // change the diags config values //
 ////////////////////////////////////
 #if !defined(__GNUC__) && !defined(hpux)
-  diags->config = c;
+  diags()->config = c;
 #else
-  memcpy(((void *)&diags->config), ((void *)&c), sizeof(DiagsConfigState));
+  memcpy(((void *)&diags()->config), ((void *)&c), sizeof(DiagsConfigState));
 #endif
 }
 
@@ -89,7 +87,7 @@ init_diags(const char *bdt, const char *bat)
   char diags_logpath[500];
   strcpy(diags_logpath, DIAGS_LOG_FILE);
 
-  diags = new Diags("Client", bdt, bat, new BaseLogFile(diags_logpath));
+  DiagsPtr::set(new Diags("Client", bdt, bat, new BaseLogFile(diags_logpath)));
   Status("opened %s", diags_logpath);
 
   reconfigure_diags();
diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc
index 1779487a6..8743e1701 100644
--- a/src/traffic_server/InkAPI.cc
+++ b/src/traffic_server/InkAPI.cc
@@ -24,15 +24,13 @@
 #include <cstdio>
 #include <atomic>
 #include <string_view>
-#include <tuple>
-#include <unordered_map>
-#include <string_view>
 
 #include "tscore/ink_platform.h"
 #include "tscore/ink_base64.h"
 #include "tscore/PluginUserArgs.h"
 #include "tscore/I_Layout.h"
 #include "tscore/I_Version.h"
+#include "tscore/Diags.h"
 
 #include "InkAPIInternal.h"
 #include "Log.h"
@@ -7829,17 +7827,17 @@ ink_sanity_check_stat_structure(void *obj)
 int
 TSIsDebugTagSet(const char *t)
 {
-  return is_debug_tag_set(t);
+  return diags()->on_for_TSDebug(t);
 }
 
 void
 TSDebugSpecific(int debug_flag, const char *tag, const char *format_str, ...)
 {
-  if ((debug_flag && diags->on()) || is_debug_tag_set(tag)) {
+  if ((debug_flag && diags()->on_for_TSDebug()) || diags()->on_for_TSDebug(tag)) {
     va_list ap;
 
     va_start(ap, format_str);
-    diags->print_va(tag, DL_Diag, nullptr, format_str, ap);
+    diags()->print_va(tag, DL_Diag, nullptr, format_str, ap);
     va_end(ap);
   }
 }
@@ -7849,15 +7847,25 @@ TSDebugSpecific(int debug_flag, const char *tag, const char *format_str, ...)
 void
 TSDebug(const char *tag, const char *format_str, ...)
 {
-  if (is_debug_tag_set(tag)) {
+  if (diags()->on_for_TSDebug() && diags()->tag_activated(tag)) {
     va_list ap;
 
     va_start(ap, format_str);
-    diags->print_va(tag, DL_Diag, nullptr, format_str, ap);
+    diags()->print_va(tag, DL_Diag, nullptr, format_str, ap);
     va_end(ap);
   }
 }
 
+void
+_TSDbg(const char *tag, const char *format_str, ...)
+{
+  va_list ap;
+
+  va_start(ap, format_str);
+  diags()->print_va(tag, DL_Diag, nullptr, format_str, ap);
+  va_end(ap);
+}
+
 /**************************   Logging API   ****************************/
 
 TSReturnCode
@@ -10413,3 +10421,12 @@ TSHttpTxnPostBufferReaderGet(TSHttpTxn txnp)
   HttpSM *sm = (HttpSM *)txnp;
   return (TSIOBufferReader)sm->get_postbuf_clone_reader();
 }
+
+tsapi TSDbgCtl const *
+TSDbgCtlCreate(char const *tag)
+{
+  sdk_assert(tag != nullptr);
+  sdk_assert(*tag != '\0');
+
+  return DbgCtl::_get_ptr(tag);
+}
diff --git a/src/traffic_server/traffic_server.cc b/src/traffic_server/traffic_server.cc
index efc7dc4be..d4f25d4af 100644
--- a/src/traffic_server/traffic_server.cc
+++ b/src/traffic_server/traffic_server.cc
@@ -295,9 +295,9 @@ public:
 
       Debug("log", "received SIGUSR2, reloading traffic.out");
       // reload output logfile (file is usually called traffic.out)
-      diags->set_std_output(StdStream::STDOUT, bind_stdout);
-      diags->set_std_output(StdStream::STDERR, bind_stderr);
-      if (diags->reseat_diagslog()) {
+      diags()->set_std_output(StdStream::STDOUT, bind_stdout);
+      diags()->set_std_output(StdStream::STDERR, bind_stderr);
+      if (diags()->reseat_diagslog()) {
         Note("Reseated %s", diags_log_filename);
       } else {
         Note("Could not reseat %s", diags_log_filename);
@@ -406,9 +406,9 @@ public:
     int diags_log_roll_int    = (int)REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_interval_sec");
     int diags_log_roll_size   = (int)REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_size_mb");
     int diags_log_roll_enable = (int)REC_ConfigReadInteger("proxy.config.diags.logfile.rolling_enabled");
-    diags->config_roll_diagslog((RollingEnabledValues)diags_log_roll_enable, diags_log_roll_int, diags_log_roll_size);
+    diags()->config_roll_diagslog((RollingEnabledValues)diags_log_roll_enable, diags_log_roll_int, diags_log_roll_size);
 
-    if (diags->should_roll_diagslog()) {
+    if (diags()->should_roll_diagslog()) {
       Note("Rolled %s", diags_log_filename);
     }
     return EVENT_CONT;
@@ -512,9 +512,9 @@ void
 set_debug_ip(const char *ip_string)
 {
   if (ip_string) {
-    diags->debug_client_ip.load(ip_string);
+    diags()->debug_client_ip.load(ip_string);
   } else {
-    diags->debug_client_ip.invalidate();
+    diags()->debug_client_ip.invalidate();
   }
 }
 
@@ -673,7 +673,7 @@ initialize_process_manager()
     EnableDeathSignal(SIGTERM);
   }
 
-  RecProcessInit(remote_management_flag ? RECM_CLIENT : RECM_STAND_ALONE, diags);
+  RecProcessInit(remote_management_flag ? RECM_CLIENT : RECM_STAND_ALONE, diags());
   LibRecordsConfigInit();
 
   // Start up manager
@@ -1780,10 +1780,10 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   // This is also needed for log rotation - setting up the file can cause privilege
   // related errors and if diagsConfig isn't get up yet that will crash on a NULL pointer.
   diagsConfig = new DiagsConfig("Server", DEFAULT_DIAGS_LOG_FILENAME, error_tags, action_tags, false);
-  diags->set_std_output(StdStream::STDOUT, bind_stdout);
-  diags->set_std_output(StdStream::STDERR, bind_stderr);
+  diags()->set_std_output(StdStream::STDOUT, bind_stdout);
+  diags()->set_std_output(StdStream::STDERR, bind_stderr);
   if (is_debug_tag_set("diags")) {
-    diags->dump();
+    diags()->dump();
   }
 
   // Bind stdout and stderr to specified switches
@@ -1878,11 +1878,11 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   }
   DiagsConfig *old_log = diagsConfig;
   diagsConfig          = new DiagsConfig("Server", diags_log_filename, error_tags, action_tags, true);
-  RecSetDiags(diags);
-  diags->set_std_output(StdStream::STDOUT, bind_stdout);
-  diags->set_std_output(StdStream::STDERR, bind_stderr);
+  RecSetDiags(diags());
+  diags()->set_std_output(StdStream::STDOUT, bind_stdout);
+  diags()->set_std_output(StdStream::STDERR, bind_stderr);
   if (is_debug_tag_set("diags")) {
-    diags->dump();
+    diags()->dump();
   }
 
   if (old_log) {
diff --git a/src/tscore/DbgCtl.cc b/src/tscore/DbgCtl.cc
new file mode 100644
index 000000000..5da3dcc4b
--- /dev/null
+++ b/src/tscore/DbgCtl.cc
@@ -0,0 +1,111 @@
+/** @file
+
+  Implementation file for DbgCtl class.
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include <mutex>
+#include <atomic>
+#include <set>
+#include <cstring>
+
+#include <tscore/Diags.h>
+
+// The resistry of fast debug controllers has a ugly implementation to handle the whole-program initialization
+// order problem with C++.
+//
+class DbgCtl::_RegistryAccessor
+{
+private:
+  struct TagCmp {
+    bool
+    operator()(TSDbgCtl const &a, TSDbgCtl const &b) const
+    {
+      return std::strcmp(a.tag, b.tag) < 0;
+    }
+  };
+
+public:
+  _RegistryAccessor() : _lg(data().mtx) {}
+
+  using Set = std::set<TSDbgCtl, TagCmp>;
+
+  struct Data {
+    std::mutex mtx;
+    Set set;
+  };
+
+  static Data &
+  data()
+  {
+    static Data d;
+    return d;
+  }
+
+private:
+  std::lock_guard<std::mutex> _lg;
+};
+
+TSDbgCtl const *
+DbgCtl::_get_ptr(char const *tag)
+{
+  ink_assert(tag != nullptr);
+
+  TSDbgCtl ctl;
+
+  ctl.tag = tag;
+
+  _RegistryAccessor ra;
+
+  auto &d{ra.data()};
+
+  if (auto it = d.set.find(ctl); it != d.set.end()) {
+    return &*it;
+  }
+
+  auto sz = std::strlen(tag);
+
+  ink_assert(sz > 0);
+
+  {
+    char *t = new char[sz + 1]; // Deleted implicitly by program termination.
+    std::memcpy(t, tag, sz + 1);
+    ctl.tag = t;
+  }
+  ctl.on = diags() && diags()->tag_activated(tag, DiagsTagType_Debug);
+
+  auto res = d.set.insert(ctl);
+
+  return &*res.first;
+}
+
+void
+DbgCtl::update()
+{
+  ink_release_assert(diags() != nullptr);
+
+  _RegistryAccessor ra;
+
+  auto &d{ra.data()};
+
+  for (auto &i : d.set) {
+    const_cast<char volatile &>(i.on) = diags()->tag_activated(i.tag, DiagsTagType_Debug);
+  }
+}
diff --git a/src/tscore/Diags.cc b/src/tscore/Diags.cc
index ef0ac93da..4cf4d5dfc 100644
--- a/src/tscore/Diags.cc
+++ b/src/tscore/Diags.cc
@@ -47,11 +47,34 @@
 #include "tscore/Regression.h"
 #include "tscore/Diags.h"
 
-int diags_on_for_plugins         = 0;
-int DiagsConfigState::enabled[2] = {0, 0};
+int diags_on_for_plugins          = 0;
+char ts_new_debug_on_flag_        = 0;
+int DiagsConfigState::_enabled[2] = {0, 0};
+
+void
+DiagsConfigState::enabled(DiagsTagType dtt, int new_value)
+{
+  if (_enabled[dtt] == new_value) {
+    return;
+  }
+  _enabled[dtt] = new_value;
+
+  if (DiagsTagType_Debug == dtt) {
+    diags_on_for_plugins  = 1 == new_value;
+    ts_new_debug_on_flag_ = (1 & new_value) != 0;
+  }
+}
 
 // Global, used for all diagnostics
-Diags *diags = nullptr;
+Diags *DiagsPtr::_diags_ptr = nullptr;
+
+void
+DiagsPtr::set(Diags *new_ptr)
+{
+  _diags_ptr = new_ptr;
+
+  DbgCtl::update();
+}
 
 static bool regression_testing_on = false;
 
@@ -123,9 +146,8 @@ Diags::Diags(std::string_view prefix_string, const char *bdt, const char *bat, B
     base_action_tags = ats_strdup(bat);
   }
 
-  config.enabled[DiagsTagType_Debug]  = (base_debug_tags != nullptr);
-  config.enabled[DiagsTagType_Action] = (base_action_tags != nullptr);
-  diags_on_for_plugins                = config.enabled[DiagsTagType_Debug];
+  config.enabled(DiagsTagType_Debug, base_debug_tags != nullptr ? 1 : 0);
+  config.enabled(DiagsTagType_Action, base_action_tags != nullptr ? 1 : 0);
 
   // The caller must always provide a non-empty prefix.
 
@@ -383,6 +405,9 @@ Diags::activate_taglist(const char *taglist, DiagsTagType mode)
     activated_tags[mode]->compile(taglist);
     unlock();
   }
+  if ((DiagsTagType_Debug == mode) && (this == diags())) {
+    DbgCtl::update();
+  }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -404,6 +429,9 @@ Diags::deactivate_all(DiagsTagType mode)
     activated_tags[mode] = nullptr;
   }
   unlock();
+  if ((DiagsTagType_Debug == mode) && (this == diags())) {
+    DbgCtl::update();
+  }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -454,9 +482,9 @@ Diags::dump(FILE *fp) const
   int i;
 
   fprintf(fp, "Diags:\n");
-  fprintf(fp, "  debug.enabled: %d\n", config.enabled[DiagsTagType_Debug]);
+  fprintf(fp, "  debug.enabled: %d\n", config.enabled(DiagsTagType_Debug));
   fprintf(fp, "  debug default tags: '%s'\n", (base_debug_tags ? base_debug_tags : "NULL"));
-  fprintf(fp, "  action.enabled: %d\n", config.enabled[DiagsTagType_Action]);
+  fprintf(fp, "  action.enabled: %d\n", config.enabled(DiagsTagType_Action));
   fprintf(fp, "  action default tags: '%s'\n", (base_action_tags ? base_action_tags : "NULL"));
   fprintf(fp, "  outputs:\n");
   for (i = 0; i < DiagsLevel_Count; i++) {
diff --git a/src/tscore/LogMessage.cc b/src/tscore/LogMessage.cc
index d576121e7..46938212e 100644
--- a/src/tscore/LogMessage.cc
+++ b/src/tscore/LogMessage.cc
@@ -84,7 +84,7 @@ LogMessage::standard_message_helper(DiagsLevel level, SourceLocation const &loc,
 {
   message_helper(
     _default_log_throttling_interval.load(),
-    [level, &loc](const char *fmt, va_list args) { diags->error_va(level, &loc, fmt, args); }, fmt, args);
+    [level, &loc](const char *fmt, va_list args) { diags()->error_va(level, &loc, fmt, args); }, fmt, args);
 }
 
 void
@@ -92,7 +92,7 @@ LogMessage::message_debug_helper(const char *tag, DiagsLevel level, SourceLocati
 {
   message_helper(
     _default_debug_throttling_interval.load(),
-    [tag, level, &loc](const char *fmt, va_list args) { diags->log_va(tag, level, &loc, fmt, args); }, fmt, args);
+    [tag, level, &loc](const char *fmt, va_list args) { diags()->log_va(tag, level, &loc, fmt, args); }, fmt, args);
 }
 
 void
@@ -100,7 +100,7 @@ LogMessage::message_print_helper(const char *tag, DiagsLevel level, SourceLocati
 {
   message_helper(
     _default_debug_throttling_interval.load(),
-    [tag, level, &loc](const char *fmt, va_list args) { diags->print_va(tag, level, &loc, fmt, args); }, fmt, args);
+    [tag, level, &loc](const char *fmt, va_list args) { diags()->print_va(tag, level, &loc, fmt, args); }, fmt, args);
 }
 
 LogMessage::LogMessage(bool is_throttled)
@@ -124,15 +124,6 @@ LogMessage::diag(const char *tag, SourceLocation const &loc, const char *fmt, ..
   va_end(args);
 }
 
-void
-LogMessage::debug(const char *tag, SourceLocation const &loc, const char *fmt, ...)
-{
-  va_list args;
-  va_start(args, fmt);
-  message_debug_helper(tag, DL_Debug, loc, fmt, args);
-  va_end(args);
-}
-
 void
 LogMessage::status(SourceLocation const &loc, const char *fmt, ...)
 {
diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am
index e5b6ed6eb..fb077d64a 100644
--- a/src/tscore/Makefile.am
+++ b/src/tscore/Makefile.am
@@ -61,6 +61,7 @@ libtscore_la_SOURCES = \
 	ConsistentHash.cc \
 	ContFlags.cc \
 	CryptoHash.cc \
+	DbgCtl.cc \
 	Diags.cc \
 	Errata.cc \
 	EventNotify.cc \
diff --git a/src/tscore/ink_cap.cc b/src/tscore/ink_cap.cc
index b4f0ecace..03b1249b5 100644
--- a/src/tscore/ink_cap.cc
+++ b/src/tscore/ink_cap.cc
@@ -46,7 +46,7 @@ ink_mutex ElevateAccess::lock = INK_MUTEX_INIT;
 
 #define DEBUG_CREDENTIALS(tag)                                                                                               \
   do {                                                                                                                       \
-    if (is_debug_tag_set(tag)) {                                                                                             \
+    if (diags()->on(tag)) {                                                                                                  \
       uid_t uid = -1, euid = -1, suid = -1;                                                                                  \
       gid_t gid = -1, egid = -1, sgid = -1;                                                                                  \
       getresuid(&uid, &euid, &suid);                                                                                         \
@@ -60,7 +60,7 @@ ink_mutex ElevateAccess::lock = INK_MUTEX_INIT;
 
 #define DEBUG_PRIVILEGES(tag)                                                                                    \
   do {                                                                                                           \
-    if (is_debug_tag_set(tag)) {                                                                                 \
+    if (diags()->on(tag)) {                                                                                      \
       cap_t caps      = cap_get_proc();                                                                          \
       char *caps_text = cap_to_text(caps, nullptr);                                                              \
       Debug(tag, "caps='%s', core=%s, death signal=%d, thread=0x%llx", caps_text, is_dumpable(), death_signal(), \
@@ -74,7 +74,7 @@ ink_mutex ElevateAccess::lock = INK_MUTEX_INIT;
 
 #define DEBUG_PRIVILEGES(tag)                                                                       \
   do {                                                                                              \
-    if (is_debug_tag_set(tag)) {                                                                    \
+    if (diags()->on(tag)) {                                                                         \
       Debug(tag, "caps='', core=%s, death signal=%d, thread=0x%llx", is_dumpable(), death_signal(), \
             (unsigned long long)pthread_self());                                                    \
     }                                                                                               \
diff --git a/src/tscore/unit_tests/test_X509HostnameValidator.cc b/src/tscore/unit_tests/test_X509HostnameValidator.cc
index 590f4b220..14ef0d0a8 100644
--- a/src/tscore/unit_tests/test_X509HostnameValidator.cc
+++ b/src/tscore/unit_tests/test_X509HostnameValidator.cc
@@ -172,7 +172,7 @@ int
 main(int argc, const char **argv)
 {
   BaseLogFile *blf = new BaseLogFile("stdout");
-  diags            = new Diags("test_x509", nullptr, nullptr, blf);
+  DiagsPtr::set(new Diags("test_x509", nullptr, nullptr, blf));
   res_track_memory = 1;
 
   SSL_library_init();
diff --git a/tests/gold_tests/pluginTest/tsapi/test_tsapi.cc b/tests/gold_tests/pluginTest/tsapi/test_tsapi.cc
index a3aad5b45..a65d9dbe1 100644
--- a/tests/gold_tests/pluginTest/tsapi/test_tsapi.cc
+++ b/tests/gold_tests/pluginTest/tsapi/test_tsapi.cc
@@ -40,6 +40,10 @@ namespace
 {
 char PIName[] = PINAME;
 
+auto dbg_ctl = TSDbgCtlCreate(PIName);
+
+auto off_dbg_ctl = TSDbgCtlCreate("yada-yada-yada");
+
 // NOTE:  It's important to flush this after writing so that a gold test using this plugin can examine the log before TS
 // terminates.
 //
@@ -172,7 +176,11 @@ transactionContFunc(TSCont, TSEvent event, void *eventData)
 {
   logFile << "Transaction: event=" << TSHttpEventNameLookup(event) << std::endl;
 
-  TSDebug(PIName, "Transaction: event=%s(%d) eventData=%p", TSHttpEventNameLookup(event), event, eventData);
+  TSDbg(dbg_ctl, "Transaction: event=%s(%d) eventData=%p", TSHttpEventNameLookup(event), event, eventData);
+
+  TSDebug(PIName, "Should not see this, enabled set to 3");
+
+  TSDbg(off_dbg_ctl, "Should not see this, tag does not match regular expression");
 
   switch (event) {
   case TS_EVENT_HTTP_READ_REQUEST_HDR: {
@@ -205,7 +213,7 @@ globalContFunc(TSCont, TSEvent event, void *eventData)
 {
   logFile << "Global: event=" << TSHttpEventNameLookup(event) << std::endl;
 
-  TSDebug(PIName, "Global: event=%s(%d) eventData=%p", TSHttpEventNameLookup(event), event, eventData);
+  TSDbg(dbg_ctl, "Global: event=%s(%d) eventData=%p", TSHttpEventNameLookup(event), event, eventData);
 
   switch (event) {
   case TS_EVENT_HTTP_TXN_START: {
@@ -247,7 +255,7 @@ globalContFunc(TSCont, TSEvent event, void *eventData)
 TSReturnCode
 TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size)
 {
-  TSDebug(PIName, "TSRemapInit()");
+  TSDbg(dbg_ctl, "TSRemapInit()");
 
   TSReleaseAssert(api_info && errbuf && errbuf_size);
 
diff --git a/tests/gold_tests/pluginTest/tsapi/tsapi.test.py b/tests/gold_tests/pluginTest/tsapi/tsapi.test.py
index b992609e3..d4c2d22be 100644
--- a/tests/gold_tests/pluginTest/tsapi/tsapi.test.py
+++ b/tests/gold_tests/pluginTest/tsapi/tsapi.test.py
@@ -55,7 +55,7 @@ ts.Disk.records_config.update({
     'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
     'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir),
     'proxy.config.url_remap.remap_required': 1,
-    'proxy.config.diags.debug.enabled': 1,
+    'proxy.config.diags.debug.enabled': 3,
     'proxy.config.diags.debug.tags': f'http|{plugin_name}',
 })