diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 57bf2fad5abb62348c4c99b82934516fac3e68a1..e95a5f2e92c62daa57df9e3801440c31d28a465e 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -524,6 +524,16 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *tag);
    Implies grpc_server_shutdown() if one was not previously performed. */
 void grpc_server_destroy(grpc_server *server);
 
+/** Enable or disable a tracer.
+
+    Tracers (usually controlled by the environment variable GRPC_TRACE)
+    allow printf-style debugging on GRPC internals, and are useful for
+    tracking down problems in the field. 
+
+    Use of this function is not strictly thread-safe, but the 
+    thread-safety issues raised by it should not be of concern. */
+int grpc_tracer_set_enabled(const char *name, int enabled);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/core/debug/trace.c b/src/core/debug/trace.c
index 32c35e7fb3a911e82ad29209db41cb4364f8c7e0..e0b502bb9cc73b56c2c26dea87f37b9b5e0ff3df 100644
--- a/src/core/debug/trace.c
+++ b/src/core/debug/trace.c
@@ -35,6 +35,7 @@
 
 #include <string.h>
 
+#include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include "src/core/support/env.h"
@@ -80,27 +81,10 @@ static void parse(const char *s) {
   char **strings = NULL;
   size_t nstrings = 0;
   size_t i;
-  tracer *t;
   split(s, &strings, &nstrings);
 
   for (i = 0; i < nstrings; i++) {
-    const char *s = strings[i];
-    if (0 == strcmp(s, "all")) {
-      for (t = tracers; t; t = t->next) {
-        *t->flag = 1;
-      }
-    } else {
-      int found = 0;
-      for (t = tracers; t; t = t->next) {
-        if (0 == strcmp(s, t->name)) {
-          *t->flag = 1;
-          found = 1;
-        }
-      }
-      if (!found) {
-        gpr_log(GPR_ERROR, "Unknown trace var: '%s'", s);
-      }
-    }
+    grpc_tracer_set_enabled(strings[i], 1);
   }
 
   for (i = 0; i < nstrings; i++) {
@@ -121,3 +105,25 @@ void grpc_tracer_init(const char *env_var) {
     gpr_free(t);
   }
 }
+
+int grpc_tracer_set_enabled(const char *name, int enabled) {
+  tracer *t;
+  if (0 == strcmp(name, "all")) {
+    for (t = tracers; t; t = t->next) {
+      *t->flag = 1;
+    }
+  } else {
+    int found = 0;
+    for (t = tracers; t; t = t->next) {
+      if (0 == strcmp(name, t->name)) {
+        *t->flag = enabled;
+        found = 1;
+      }
+    }
+    if (!found) {
+      gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name);
+      return 0;  /* early return */
+    }
+  }
+  return 1;
+}
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c
index d32dbec25e732a5c9e71801e03f842307e7cde5e..0834987fbec1cdadb3f3aa517556b583fcf4b7a9 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c
@@ -147,6 +147,10 @@ int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
 
+  GPR_ASSERT(0 == grpc_tracer_set_enabled("also-doesnt-exist", 0));
+  GPR_ASSERT(1 == grpc_tracer_set_enabled("http", 1));
+  GPR_ASSERT(1 == grpc_tracer_set_enabled("all", 1));
+
   for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
     grpc_end2end_tests(configs[i]);
   }