#include "external-agent.h"
 #include "lock-tracking.h"
+#include "logging.h"
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
 static struct tdb_context *tdb;
 
-static void taplog(struct tdb_context *tdb,
-                  enum tdb_debug_level level,
-                  const char *fmt, ...)
-{
-       va_list ap;
-       char line[200];
-
-       va_start(ap, fmt);
-       vsprintf(line, fmt, ap);
-       va_end(ap);
-
-       diag("external: %s", line);
-}
-
 static enum agent_return do_operation(enum operation op, const char *name)
 {
-       struct tdb_logging_context logctx = { taplog, NULL };
        TDB_DATA k;
        enum agent_return ret;
        TDB_DATA data;
                        return OTHER_FAILURE;
                }
                tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0,
-                                 &logctx, NULL);
+                                 &taplogctx, NULL);
                if (!tdb) {
                        if (!locking_would_block)
                                diag("Opening tdb gave %s", strerror(errno));
                if (tdb)
                        return OTHER_FAILURE;
                tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0,
-                                 &logctx, NULL);
+                                 &taplogctx, NULL);
                ret = tdb ? SUCCESS : OTHER_FAILURE;
                break;
        case TRANSACTION_START:
 
        /* We want to fail, not block. */
        nonblocking_locks = true;
+       log_prefix = "external: ";
        while ((ret = read(command[0], name, sizeof(name))) > 0) {
                enum agent_return result;
 
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 static int tdb_expand_file_sparse(struct tdb_context *tdb,
                                  tdb_off_t size,
        struct tdb_record rec;
 
        plan_tests(24);
-       tdb = tdb_open("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        ok1(tdb);
        tdb->methods = &large_io_methods;
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 int main(int argc, char *argv[])
 {
        ok1(fd >= 0);
        ok1(write(fd, "hello world", 11) == 11);
        close(fd);
-       tdb = tdb_open("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0);
+       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0,
+                         &taplogctx, NULL);
        ok1(!tdb);
-       tdb = tdb_open("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR,
+                         0600, &taplogctx, NULL);
        ok1(tdb);
        tdb_close(tdb);
 
        ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr));
        close(fd);
 
-       tdb = tdb_open("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT, 0600);
+       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT,
+                         0600, &taplogctx, NULL);
        ok1(errno == EIO);
        ok1(!tdb);
 
        /* With truncate, will be fine. */
-       tdb = tdb_open("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT|O_TRUNC, 0600);
+       tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0,
+                         O_RDWR|O_CREAT|O_TRUNC, 0600, &taplogctx, NULL);
        ok1(tdb);
        tdb_close(tdb);
 
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 int main(int argc, char *argv[])
 {
        TDB_DATA key, data;
 
        plan_tests(9);
-       tdb = tdb_open("run-check.tdb", 1, TDB_CLEAR_IF_FIRST,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-check.tdb", 1, TDB_CLEAR_IF_FIRST,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        ok1(tdb);
        ok1(tdb_check(tdb, NULL, NULL) == 0);
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 static int check(TDB_DATA key, TDB_DATA data, void *private)
 {
 
        plan_tests(4);
        /* This should use mmap. */
-       tdb = tdb_open("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        if (!tdb)
                abort();
        tdb_close(tdb);
 
        /* This should not. */
-       tdb = tdb_open("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        if (!tdb)
                abort();
 
 #include <err.h>
 #include <setjmp.h>
 #include "external-agent.h"
+#include "logging.h"
 
 #undef write
 #undef pwrite
 #undef ftruncate
 
 static bool in_transaction;
-static bool suppress_logging;
 static int target, current;
 static jmp_buf jmpbuf;
 #define TEST_DBNAME "run-die-during-transaction.tdb"
 #define KEY_STRING "helloworld"
 
-static void taplog(struct tdb_context *tdb,
-                  enum tdb_debug_level level,
-                  const char *fmt, ...)
-{
-       va_list ap;
-       char line[200];
-
-       if (suppress_logging)
-               return;
-
-       va_start(ap, fmt);
-       vsprintf(line, fmt, ap);
-       va_end(ap);
-
-       diag("%s", line);
-}
-
 static void maybe_die(int fd)
 {
        if (in_transaction && current++ == target) {
 {
        struct tdb_context *tdb = NULL;
        TDB_DATA key;
-       struct tdb_logging_context logctx = { taplog, NULL };
        enum agent_return ret;
        int needed_recovery = 0;
 
 
        unlink(TEST_DBNAME);
        tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP,
-                         O_CREAT|O_TRUNC|O_RDWR, 0600, &logctx, NULL);
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        /* Put key for agent to fetch. */
        key.dsize = strlen(KEY_STRING);
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 int main(int argc, char *argv[])
 {
        TDB_DATA key, data;
 
        plan_tests(13);
-       tdb = tdb_open("run-endian.tdb", 1024, TDB_CLEAR_IF_FIRST|TDB_CONVERT,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-endian.tdb", 1024,
+                         TDB_CLEAR_IF_FIRST|TDB_CONVERT,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        ok1(tdb);
        key.dsize = strlen("hi");
        tdb_close(tdb);
 
        /* Reopen: should read it */
-       tdb = tdb_open("run-endian.tdb", 1024, 0, O_RDWR, 0);
+       tdb = tdb_open_ex("run-endian.tdb", 1024, 0, O_RDWR, 0,
+                         &taplogctx, NULL);
        ok1(tdb);
        
        key.dsize = strlen("hi");
 
 #include <stdlib.h>
 #include <stdbool.h>
 #include <err.h>
+#include "logging.h"
+
 int main(int argc, char *argv[])
 {
        struct tdb_context *tdb;
        key.dsize = strlen("hi");
        key.dptr = (void *)"hi";
 
-       tdb = tdb_open("run-nested-transactions.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-nested-transactions.tdb",
+                         1024, TDB_CLEAR_IF_FIRST,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
        ok1(tdb);
 
        /* No nesting by default. */
        free(data.dptr);
        tdb_close(tdb);
 
-       tdb = tdb_open("run-nested-transactions.tdb", 1024, TDB_ALLOW_NESTING, O_RDWR, 0);
+       tdb = tdb_open_ex("run-nested-transactions.tdb",
+                         1024, TDB_ALLOW_NESTING, O_RDWR, 0, &taplogctx, NULL);
        ok1(tdb);
 
        ok1(tdb_transaction_start(tdb) == 0);
 
 #include <stdbool.h>
 #include <err.h>
 #include "external-agent.h"
+#include "logging.h"
 
 static struct agent *agent;
 
        if (!agent)
                err(1, "preparing agent");
 
-       tdb = tdb_open("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
        ok1(tdb);
 
        ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS);
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 #undef fcntl
 
        int errors = 0;
 
        plan_tests(41);
-       tdb = tdb_open("run-no-lock-during-traverse.tdb",
-                      1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-no-lock-during-traverse.tdb",
+                         1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR,
+                         0600, &taplogctx, NULL);
 
        ok1(tdb);
        ok1(prepare_entries(tdb));
 
 #include <stdarg.h>
 #include <err.h>
 #include "external-agent.h"
+#include "logging.h"
 
 static struct agent *agent;
 static bool opened;
 #undef fcntl
 #undef ftruncate
 
-static void taplog(struct tdb_context *tdb,
-                  enum tdb_debug_level level,
-                  const char *fmt, ...)
-{
-       va_list ap;
-       char line[200];
-
-       va_start(ap, fmt);
-       vsprintf(line, fmt, ap);
-       va_end(ap);
-
-       diag("%s", line);
-}
-
 static bool is_same(const char *snapshot, const char *latest, off_t len)
 {
        unsigned i;
 
 int main(int argc, char *argv[])
 {
-       struct tdb_logging_context logctx = { taplog, NULL };
        const int flags[] = { TDB_DEFAULT,
                              TDB_CLEAR_IF_FIRST,
                              TDB_NOMMAP, 
                unlink(TEST_DBNAME);
                tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i],
                                  O_CREAT|O_TRUNC|O_RDWR, 0600,
-                                 &logctx, NULL);
+                                 &taplogctx, NULL);
                ok1(tdb);
 
                opened = true;
 
 #include <stdbool.h>
 #include <err.h>
 #include "external-agent.h"
+#include "logging.h"
 
 static struct agent *agent;
 
        if (!agent)
                err(1, "preparing agent");
 
-       tdb = tdb_open("run-traverse-in-transaction.tdb",
-                      1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run-traverse-in-transaction.tdb",
+                         1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR,
+                         0600, &taplogctx, NULL);
        ok1(tdb);
 
        key.dsize = strlen("hi");
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 int main(int argc, char *argv[])
 {
        TDB_DATA key, data;
 
        plan_tests(4);
-       tdb = tdb_open(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR,
+                         0600, &taplogctx, NULL);
        ok1(tdb);
 
        /* Tickle bug on appending zero length buffer to zero length buffer. */
 
 #include <ccan/tap/tap.h>
 #include <stdlib.h>
 #include <err.h>
+#include "logging.h"
 
 int main(int argc, char *argv[])
 {
        TDB_DATA key, data;
 
        plan_tests(10);
-       tdb = tdb_open("run.tdb", 1024, TDB_CLEAR_IF_FIRST,
-                      O_CREAT|O_TRUNC|O_RDWR, 0600);
+       tdb = tdb_open_ex("run.tdb", 1024, TDB_CLEAR_IF_FIRST,
+                         O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
 
        ok1(tdb);
        key.dsize = strlen("hi");