From fbe696a61c17e60803b1cbc162359cbed83f400c Mon Sep 17 00:00:00 2001
From: Ryan Nett <rnett@calpoly.edu>
Date: Fri, 25 Jun 2021 12:02:23 -0700
Subject: [PATCH 1/3] Start of log sink mapping

Signed-off-by: Ryan Nett <rnett@calpoly.edu>
---
 tensorflow-core/tensorflow-core-api/pom.xml   |   2 +
 .../internal/c_api/TFDefaultLogSink.java      |  36 ++
 .../tensorflow/internal/c_api/TFLogEntry.java |  43 ++
 .../tensorflow/internal/c_api/TFLogSink.java  |  38 ++
 .../internal/c_api/global/tensorflow.java     | 460 ++++++++++++++++++
 .../internal/c_api/presets/tensorflow.java    |  49 +-
 6 files changed, 626 insertions(+), 2 deletions(-)
 create mode 100644 tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java
 create mode 100644 tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
 create mode 100644 tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java

diff --git a/tensorflow-core/tensorflow-core-api/pom.xml b/tensorflow-core/tensorflow-core-api/pom.xml
index 4ebe1234e80..fd96cca67fd 100644
--- a/tensorflow-core/tensorflow-core-api/pom.xml
+++ b/tensorflow-core/tensorflow-core-api/pom.xml
@@ -212,6 +212,8 @@
           <includePaths>
             <includePath>${project.basedir}/</includePath>
             <includePath>${project.basedir}/bazel-${project.artifactId}/external/org_tensorflow/</includePath>
+            <includePath>${project.basedir}/bazel-${project.artifactId}/external/com_google_absl/</includePath>
+            <includePath>${project.basedir}/bazel-${project.artifactId}/external/eigen_archive/</includePath>
           </includePaths>
           <linkPaths>
             <linkPath>${project.basedir}/bazel-bin/external/llvm_openmp/</linkPath>
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java
new file mode 100644
index 00000000000..8ec76ade84a
--- /dev/null
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java
@@ -0,0 +1,36 @@
+// Targeted by JavaCPP version 1.5.4: DO NOT EDIT THIS FILE
+
+package org.tensorflow.internal.c_api;
+
+import java.nio.*;
+import org.bytedeco.javacpp.*;
+import org.bytedeco.javacpp.annotation.*;
+
+import static org.tensorflow.internal.c_api.global.tensorflow.*;
+
+
+// This is the default log sink. This log sink is used if there are no other
+// log sinks registered. To disable the default log sink, set the
+// "no_default_logger" Bazel config setting to true or define a
+// NO_DEFAULT_LOGGER preprocessor symbol. This log sink will always log to
+// stderr.
+@Namespace("tensorflow") @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class)
+public class TFDefaultLogSink extends TFLogSink {
+    static { Loader.load(); }
+    /** Default native constructor. */
+    public TFDefaultLogSink() { super((Pointer)null); allocate(); }
+    /** Native array allocator. Access with {@link Pointer#position(long)}. */
+    public TFDefaultLogSink(long size) { super((Pointer)null); allocateArray(size); }
+    /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
+    public TFDefaultLogSink(Pointer p) { super(p); }
+    private native void allocate();
+    private native void allocateArray(long size);
+    @Override public TFDefaultLogSink position(long position) {
+        return (TFDefaultLogSink)super.position(position);
+    }
+    @Override public TFDefaultLogSink getPointer(long i) {
+        return new TFDefaultLogSink(this).position(position + i);
+    }
+
+  public native void Send(@Const @ByRef TFLogEntry entry);
+}
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
new file mode 100644
index 00000000000..13514222b89
--- /dev/null
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
@@ -0,0 +1,43 @@
+// Targeted by JavaCPP version 1.5.4: DO NOT EDIT THIS FILE
+
+package org.tensorflow.internal.c_api;
+
+import java.nio.*;
+import org.bytedeco.javacpp.*;
+import org.bytedeco.javacpp.annotation.*;
+
+import static org.tensorflow.internal.c_api.global.tensorflow.*;
+  // namespace internal
+
+// LogSink support adapted from //base/logging.h
+//
+// `LogSink` is an interface which can be extended to intercept and process
+// all log messages. LogSink implementations must be thread-safe. A single
+// instance will be called from whichever thread is performing a logging
+// operation.
+@Namespace("tensorflow") @NoOffset @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class)
+public class TFLogEntry extends Pointer {
+    static { Loader.load(); }
+    /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
+    public TFLogEntry(Pointer p) { super(p); }
+
+  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, message); }
+  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message);
+  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, message); }
+  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String message);
+
+  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line,
+                        @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, fname, line, message); }
+  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line,
+                        @StdString @Cast({"char*", "std::string&&"}) BytePointer message);
+  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line,
+                        @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, fname, line, message); }
+  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line,
+                        @StdString @Cast({"char*", "std::string&&"}) String message);
+
+  public native @Cast("absl::LogSeverity") int log_severity();
+  public native @StdString @Cast({"char*", "std::string&&"}) BytePointer FName();
+  public native int Line();
+  public native @StdString @Cast({"char*", "std::string&&"}) BytePointer ToString();
+  public native @StdString @Cast({"char*", "std::string&&"}) BytePointer text_message();
+}
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java
new file mode 100644
index 00000000000..456b6dbbbd8
--- /dev/null
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java
@@ -0,0 +1,38 @@
+// Targeted by JavaCPP version 1.5.4: DO NOT EDIT THIS FILE
+
+package org.tensorflow.internal.c_api;
+
+import java.nio.*;
+import org.bytedeco.javacpp.*;
+import org.bytedeco.javacpp.annotation.*;
+
+import static org.tensorflow.internal.c_api.global.tensorflow.*;
+
+
+@Namespace("tensorflow") @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class)
+public class TFLogSink extends Pointer {
+    static { Loader.load(); }
+    /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
+    public TFLogSink(Pointer p) { super(p); }
+
+
+  // `Send` is called synchronously during the log statement.  The logging
+  // module guarantees not to call `Send` concurrently on the same log sink.
+  // Implementations should be careful not to call`LOG` or `CHECK` or take
+  // any locks that might be held by the `LOG` caller, to avoid deadlock.
+  //
+  // `e` is guaranteed to remain valid until the subsequent call to
+  // `WaitTillSent` completes, so implementations may store a pointer to or
+  // copy of `e` (e.g. in a thread local variable) for use in `WaitTillSent`.
+  public native void Send(@Const @ByRef TFLogEntry entry);
+
+  // `WaitTillSent` blocks the calling thread (the thread that generated a log
+  // message) until the sink has finished processing the log message.
+  // `WaitTillSent` is called once per log message, following the call to
+  // `Send`.  This may be useful when log messages are buffered or processed
+  // asynchronously by an expensive log sink.
+  // The default implementation returns immediately.  Like `Send`,
+  // implementations should be careful not to call `LOG` or `CHECK or take any
+  // locks that might be held by the `LOG` caller, to avoid deadlock.
+  public native void WaitTillSent();
+}
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java
index b345ab4dad2..a9a68b12e9f 100644
--- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java
@@ -4739,4 +4739,464 @@ public static native void TFE_ContextExportRunMetadata(TFE_Context ctx,
 // #endif  // TENSORFLOW_C_EAGER_C_API_H_
 
 
+// Parsed from tensorflow/core/platform/default/logging.h
+
+/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
+
+Licensed 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.
+==============================================================================*/
+
+// #ifndef TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_
+// #define TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_
+
+// IWYU pragma: private, include "third_party/tensorflow/core/platform/logging.h"
+// IWYU pragma: friend third_party/tensorflow/core/platform/logging.h
+
+// #include <atomic>
+// #include <limits>
+// #include <memory>
+// #include <sstream>
+// #include <vector>
+
+// #include "absl/base/log_severity.h"
+// #include "absl/strings/string_view.h"
+// #include "tensorflow/core/platform/macros.h"
+// #include "tensorflow/core/platform/types.h"
+
+// TODO(mrry): Prevent this Windows.h #define from leaking out of our headers.
+// #undef ERROR
+            // base_logging::INFO;
+         // base_logging::WARNING;
+           // base_logging::ERROR;
+           // base_logging::FATAL;
+  // base_logging::NUM_SEVERITIES;
+
+// Uses the lower operator & precedence to voidify a LogMessage reference, so
+// that the ternary VLOG() implementation is balanced, type wise.
+
+// LogMessageFatal ensures the process will exit in failure after
+// logging this message.
+
+// LogMessageNull supports the DVLOG macro by simply dropping any log messages.
+
+// #define _TF_LOG_INFO
+//   ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::INFO)
+// #define _TF_LOG_WARNING
+//   ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::WARNING)
+// #define _TF_LOG_ERROR
+//   ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::ERROR)
+// #define _TF_LOG_FATAL
+//   ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__)
+
+// #define _TF_LOG_QFATAL _TF_LOG_FATAL
+
+// #define LOG(severity) _TF_LOG_##severity
+
+// #ifdef IS_MOBILE_PLATFORM
+
+// Turn VLOG off when under mobile devices for considerations of binary size.
+// #define VLOG_IS_ON(lvl) ((lvl) <= 0)
+
+// #else
+
+// Otherwise, set TF_CPP_MAX_VLOG_LEVEL environment to update minimum log level
+// of VLOG, or TF_CPP_VMODULE to set the minimum log level for individual
+// translation units.
+// #define VLOG_IS_ON(lvl)
+//   (([](int level, const char* fname) {
+//     static const bool vmodule_activated =
+//         ::tensorflow::internal::LogMessage::VmoduleActivated(fname, level);
+//     return vmodule_activated;
+//   })(lvl, __FILE__))
+
+// #endif
+
+// #define VLOG(level)
+//   TF_PREDICT_TRUE(!VLOG_IS_ON(level))
+//   ? (void)0
+//   : ::tensorflow::internal::Voidifier() &
+//           ::tensorflow::internal::LogMessage(__FILE__, __LINE__,
+//                                              tensorflow::INFO)
+
+// `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`).
+// Otherwise, it compiles away and does nothing.
+// #ifndef NDEBUG
+// #define DVLOG VLOG
+// #else
+// #define DVLOG(verbose_level)
+//   while (false && (verbose_level) > 0) ::tensorflow::internal::LogMessageNull()
+// #endif
+
+// This macro has a lot going on!
+//
+// * A local static (`logging_internal_stateful_condition_state`) is
+//   declared in a scope such that each `LOG_EVERY_N` (etc.) line has its own
+//   state.
+// * `COUNTER`, the third variable, is used to support `<< COUNTER`. It is not
+//   mangled, so shadowing can be a problem, albeit more of a
+//   shoot-yourself-in-the-foot one.  Don't name your variables `COUNTER`.
+// * A single for loop can declare state and also test
+//   `condition && state.ShouldLog()`, but there's no way to constrain it to run
+//   only once (or not at all) without declaring another variable.  The outer
+//   for-loop declares this variable (`do_log`).
+// * Using for loops instead of if statements means there's no risk of an
+//   ambiguous dangling else statement.
+// #define LOGGING_INTERNAL_STATEFUL_CONDITION(kind, condition, arg)
+//   for (bool logging_internal_stateful_condition_do_log(condition);
+//        logging_internal_stateful_condition_do_log;
+//        logging_internal_stateful_condition_do_log = false)
+//     for (static ::tensorflow::internal::Log##kind##State
+//              logging_internal_stateful_condition_state;
+//          logging_internal_stateful_condition_do_log &&
+//          logging_internal_stateful_condition_state.ShouldLog(arg);
+//          logging_internal_stateful_condition_do_log = false)
+//       for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED =
+//                logging_internal_stateful_condition_state.counter();
+//            logging_internal_stateful_condition_do_log;
+//            logging_internal_stateful_condition_do_log = false)
+
+// An instance of `LOG_EVERY_N` increments a hidden zero-initialized counter
+// every time execution passes through it and logs the specified message when
+// the counter's value is a multiple of `n`, doing nothing otherwise.  Each
+// instance has its own counter.  The counter's value can be logged by streaming
+// the symbol `COUNTER`.  `LOG_EVERY_N` is thread-safe.
+// Example:
+//
+//   for (const auto& user : all_users) {
+//     LOG_EVERY_N(INFO, 1000) << "Processing user #" << COUNTER;
+//     ProcessUser(user);
+//   }
+// #define LOG_EVERY_N(severity, n)
+//   LOGGING_INTERNAL_STATEFUL_CONDITION(EveryN, true, n)
+//   LOG(severity)
+// `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is
+// logged when the counter's value is less than `n`.  `LOG_FIRST_N` is
+// thread-safe.
+// #define LOG_FIRST_N(severity, n)
+//   LOGGING_INTERNAL_STATEFUL_CONDITION(FirstN, true, n)
+//   LOG(severity)
+// `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified
+// message is logged when the counter's value is a power of 2.
+// `LOG_EVERY_POW_2` is thread-safe.
+// #define LOG_EVERY_POW_2(severity)
+//   LOGGING_INTERNAL_STATEFUL_CONDITION(EveryPow2, true, 0)
+//   LOG(severity)
+// An instance of `LOG_EVERY_N_SEC` uses a hidden state variable to log the
+// specified message at most once every `n_seconds`.  A hidden counter of
+// executions (whether a message is logged or not) is also maintained and can be
+// logged by streaming the symbol `COUNTER`.  `LOG_EVERY_N_SEC` is thread-safe.
+// Example:
+//
+//   LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far";
+// #define LOG_EVERY_N_SEC(severity, n_seconds)
+//   LOGGING_INTERNAL_STATEFUL_CONDITION(EveryNSec, true, n_seconds)
+//   LOG(severity)
+
+// CHECK dies with a fatal error if condition is not true.  It is *not*
+// controlled by NDEBUG, so the check will be executed regardless of
+// compilation mode.  Therefore, it is safe to do things like:
+//    CHECK(fp->Write(x) == 4)
+// #define CHECK(condition)
+//   if (TF_PREDICT_FALSE(!(condition)))
+//   LOG(FATAL) << "Check failed: " #condition " "
+
+// Function is overloaded for integral types to allow static const
+// integrals declared in classes and not defined to be used as arguments to
+// CHECK* macros. It's not encouraged though.
+
+
+
+
+
+
+
+
+
+
+
+// This formats a value for a failing CHECK_XX statement.  Ordinarily,
+// it uses the definition for operator<<, with a few special cases below.
+
+// Overrides for char types provide readable values for unprintable
+// characters.
+@Namespace("tensorflow::internal") public static native void MakeCheckOpValueString(@Cast("std::ostream*") Pointer os, @Cast("const char") byte v);
+
+// #if LANG_CXX11
+// We need an explicit specialization for std::nullptr_t.
+@Namespace("tensorflow::internal") public static native void MakeCheckOpValueString(@Cast("std::ostream*") Pointer os, Pointer v);
+// #endif
+
+// A container for a string pointer which can be evaluated to a bool -
+// true iff the pointer is non-NULL.
+
+// Build the error message string. Specify no inlining for code size.
+
+// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
+// statement.  See MakeCheckOpString for sample usage.  Other
+// approaches were considered: use of a template method (e.g.,
+// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
+// base::Print<T2>, &v2), however this approach has complications
+// related to volatile arguments and function-pointer arguments).
+
+// Helper functions for CHECK_OP macro.
+// The (int, int) specialization works around the issue that the compiler
+// will not instantiate the template version of the function on values of
+// unnamed enum type - see comment below.
+// The (size_t, int) and (int, size_t) specialization are to handle unsigned
+// comparison errors while still being thorough with the comparison.
+// #define TF_DEFINE_CHECK_OP_IMPL(name, op)
+//   template <typename T1, typename T2>
+//   inline string* name##Impl(const T1& v1, const T2& v2,
+//                             const char* exprtext) {
+//     if (TF_PREDICT_TRUE(v1 op v2))
+//       return NULL;
+//     else
+//       return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext);
+//   }
+//   inline string* name##Impl(int v1, int v2, const char* exprtext) {
+//     return name##Impl<int, int>(v1, v2, exprtext);
+//   }
+//   inline string* name##Impl(const size_t v1, const int v2,
+//                             const char* exprtext) {
+//     if (TF_PREDICT_FALSE(v2 < 0)) {
+//       return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext);
+//     }
+//     return name##Impl<size_t, size_t>(v1, v2, exprtext);
+//   }
+//   inline string* name##Impl(const int v1, const size_t v2,
+//                             const char* exprtext) {
+//     if (TF_PREDICT_FALSE(v2 >= std::numeric_limits<int>::max())) {
+//       return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext);
+//     }
+//     const size_t uval = (size_t)((unsigned)v2);
+//     return name##Impl<size_t, size_t>(v1, uval, exprtext);
+//   }
+
+// We use the full name Check_EQ, Check_NE, etc. in case the file including
+// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
+// This happens if, for example, those are used as token names in a
+// yacc grammar.
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, int v2, String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(@Cast("const size_t") long v1, int v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(@Cast("const size_t") long v1, int v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, @Cast("const size_t") long v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, @Cast("const size_t") long v2,
+                              String exprtext);  // Compilation error with CHECK_EQ(NULL, x)?
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, int v2, String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(@Cast("const size_t") long v1, int v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(@Cast("const size_t") long v1, int v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, @Cast("const size_t") long v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, @Cast("const size_t") long v2,
+                              String exprtext);  // Use CHECK(x == NULL) instead.
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, int v2, String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(@Cast("const size_t") long v1, int v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(@Cast("const size_t") long v1, int v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, @Cast("const size_t") long v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, @Cast("const size_t") long v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, int v2, String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(@Cast("const size_t") long v1, int v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(@Cast("const size_t") long v1, int v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, @Cast("const size_t") long v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, @Cast("const size_t") long v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, int v2, String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(@Cast("const size_t") long v1, int v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(@Cast("const size_t") long v1, int v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, @Cast("const size_t") long v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, @Cast("const size_t") long v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, int v2, String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(@Cast("const size_t") long v1, int v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(@Cast("const size_t") long v1, int v2,
+                              String exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, @Cast("const size_t") long v2,
+                              @Cast("const char*") BytePointer exprtext);
+  @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, @Cast("const size_t") long v2,
+                              String exprtext);
+// #undef TF_DEFINE_CHECK_OP_IMPL
+
+// In optimized mode, use CheckOpString to hint to compiler that
+// the while condition is unlikely.
+// #define CHECK_OP_LOG(name, op, val1, val2)
+//   while (::tensorflow::internal::CheckOpString _result{
+//       ::tensorflow::internal::name##Impl(
+//           ::tensorflow::internal::GetReferenceableValue(val1),
+//           ::tensorflow::internal::GetReferenceableValue(val2),
+//           #val1 " " #op " " #val2)})
+//   ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__) << *(_result.str_)
+
+// #define CHECK_OP(name, op, val1, val2) CHECK_OP_LOG(name, op, val1, val2)
+
+// CHECK_EQ/NE/...
+// #define CHECK_EQ(val1, val2) CHECK_OP(Check_EQ, ==, val1, val2)
+// #define CHECK_NE(val1, val2) CHECK_OP(Check_NE, !=, val1, val2)
+// #define CHECK_LE(val1, val2) CHECK_OP(Check_LE, <=, val1, val2)
+// #define CHECK_LT(val1, val2) CHECK_OP(Check_LT, <, val1, val2)
+// #define CHECK_GE(val1, val2) CHECK_OP(Check_GE, >=, val1, val2)
+// #define CHECK_GT(val1, val2) CHECK_OP(Check_GT, >, val1, val2)
+// #define CHECK_NOTNULL(val)
+//   ::tensorflow::internal::CheckNotNull(__FILE__, __LINE__,
+//                                        "'" #val "' Must be non NULL", (val))
+
+// #ifndef NDEBUG
+// DCHECK_EQ/NE/...
+// #define DCHECK(condition) CHECK(condition)
+// #define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
+// #define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
+// #define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
+// #define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
+// #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
+// #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
+
+// #else
+
+// #define DCHECK(condition)
+//   while (false && (condition)) LOG(FATAL)
+
+// NDEBUG is defined, so DCHECK_EQ(x, y) and so on do nothing.
+// However, we still want the compiler to parse x and y, because
+// we don't want to lose potentially useful errors and warnings.
+// _DCHECK_NOP is a helper, and should not be used outside of this file.
+// #define _TF_DCHECK_NOP(x, y)
+//   while (false && ((void)(x), (void)(y), 0)) LOG(FATAL)
+
+// #define DCHECK_EQ(x, y) _TF_DCHECK_NOP(x, y)
+// #define DCHECK_NE(x, y) _TF_DCHECK_NOP(x, y)
+// #define DCHECK_LE(x, y) _TF_DCHECK_NOP(x, y)
+// #define DCHECK_LT(x, y) _TF_DCHECK_NOP(x, y)
+// #define DCHECK_GE(x, y) _TF_DCHECK_NOP(x, y)
+// #define DCHECK_GT(x, y) _TF_DCHECK_NOP(x, y)
+
+// #endif
+
+// These are for when you don't want a CHECK failure to print a verbose
+// stack trace.  The implementation of CHECK* in this file already doesn't.
+// #define QCHECK(condition) CHECK(condition)
+// #define QCHECK_EQ(x, y) CHECK_EQ(x, y)
+// #define QCHECK_NE(x, y) CHECK_NE(x, y)
+// #define QCHECK_LE(x, y) CHECK_LE(x, y)
+// #define QCHECK_LT(x, y) CHECK_LT(x, y)
+// #define QCHECK_GE(x, y) CHECK_GE(x, y)
+// #define QCHECK_GT(x, y) CHECK_GT(x, y)
+
+@Namespace("tensorflow::internal") public static native @Cast("tensorflow::int64") long MinLogLevelFromEnv();
+
+@Namespace("tensorflow::internal") public static native @Cast("tensorflow::int64") long MaxVLogLevelFromEnv();
+
+
+// Targeting ../TFLogEntry.java
+
+
+// Targeting ../TFLogSink.java
+
+
+// Targeting ../TFDefaultLogSink.java
+
+
+
+// Add or remove a `LogSink` as a consumer of logging data.  Thread-safe.
+@Namespace("tensorflow") public static native void TFAddLogSink(TFLogSink sink);
+@Namespace("tensorflow") public static native void TFRemoveLogSink(TFLogSink sink);
+
+// Get all the log sinks.  Thread-safe.
+@Namespace("tensorflow") public static native @Cast("tensorflow::TFLogSink**") @StdVector PointerPointer TFGetLogSinks();
+
+  // namespace tensorflow
+
+// #endif  // TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_
+
+
+// Parsed from absl/base/log_severity.h
+
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed 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
+//
+//      https://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.
+
+// #ifndef ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
+// #define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
+
+// #include <array>
+// #include <ostream>
+
+// #include "absl/base/attributes.h"
+// #include "absl/base/config.h"
+/** enum class absl::LogSeverity */
+public static final int
+  kInfo = 0,
+  kWarning = 1,
+  kError = 2,
+  kFatal = 3;
+
+// LogSeverities()
+//
+// Returns an iterable of all standard `absl::LogSeverity` values, ordered from
+// least to most severe.
+
+
+// LogSeverityName()
+//
+// Returns the all-caps string representation (e.g. "INFO") of the specified
+// severity level if it is one of the standard levels and "UNKNOWN" otherwise.
+@Namespace("absl") public static native @Cast("const char*") BytePointer LogSeverityName(@Cast("absl::LogSeverity") int s);
+
+// NormalizeLogSeverity()
+//
+// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal`
+// normalize to `kError` (**NOT** `kFatal`).
+@Namespace("absl") public static native @Cast("const absl::LogSeverity") int NormalizeLogSeverity(@Cast("absl::LogSeverity") int s);
+
+// operator<<
+//
+// The exact representation of a streamed `absl::LogSeverity` is deliberately
+// unspecified; do not rely on it.
+@Namespace("absl") public static native @Cast("std::ostream*") @ByRef @Name("operator <<") Pointer shiftLeft(@Cast("std::ostream*") @ByRef Pointer os, @Cast("absl::LogSeverity") int s);
+
+  // namespace absl
+
+// #endif  // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
+
+
 }
diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
index 6cb3be62eb7..8eaec809863 100644
--- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
+++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
@@ -46,7 +46,9 @@
             //                "tensorflow/c/env.h",
             "tensorflow/c/kernels.h",
             "tensorflow/c/ops.h",
-            "tensorflow/c/eager/c_api.h"
+            "tensorflow/c/eager/c_api.h",
+            "tensorflow/core/platform/default/logging.h",
+            "absl/base/log_severity.h"
           },
           link = "tensorflow_cc@.2",
           preload = {"iomp5", "mklml", "mklml_intel", "tensorflow_framework@.2"},
@@ -385,6 +387,49 @@ public void map(InfoMap infoMap) {
                     "TF_ShapeInferenceContextDimValueKnown",
                     "TFE_NewTensorHandle(const tensorflow::Tensor&, TF_Status*)",
                     "TF_InitKernel")
-                .skip());
+                .skip())
+        .put(
+            new Info("tensorflow::uint32", "tensorflow::int32", "uint32", "int32")
+                .cast()
+                .valueTypes("int")
+                .pointerTypes("IntPointer", "int[]"))
+        .put(
+            new Info("tensorflow::int16", "tensorflow::uint16", "int16", "uint16")
+                .cast()
+                .valueTypes("short")
+                .pointerTypes("ShortPointer", "short[]"))
+        .put(
+            new Info("tensorflow::uint64", "tensorflow::int64", "int64", "uint64")
+                .cast()
+                .valueTypes("long")
+                .pointerTypes("LongPointer", "long[]"))
+        .put(new Info("absl::string_view", "absl::lts_2020_09_23::string_view", "string", "std::string", "tensorflow::string").annotations("@StdString")
+            .valueTypes("@Cast({\"char*\", \"std::string&&\"}) BytePointer", "@Cast({\"char*\", \"std::string&&\"}) String")
+            .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer"))
+    .put(new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity").cast().valueTypes("int").pointerTypes("IntPointer", "int[]"))
+    .put(new Info("tensorflow::internal::LogEveryNSecState",
+        "tensorflow::internal::LogEveryNState",
+        "tensorflow::internal::LogEveryPow2State",
+        "tensorflow::internal::LogFirstNState",
+        "tensorflow::internal::Voidifier",
+        "tensorflow::internal::LogMessage",
+        "tensorflow::internal::LogMessageFatal",
+        "tensorflow::internal::LogMessageNull",
+        "tensorflow::internal::CheckOpMessageBuilder",
+        "tensorflow::internal::CheckOpString",
+        "tensorflow::internal::GetReferenceableValue",
+        "DVLOG",
+        "absl::LogSeverities").skip())
+    .put(new Info(
+        "tensorflow::INFO",
+        "tensorflow::WARNING",
+        "tensorflow::ERROR",
+        "tensorflow::FATAL",
+        "tensorflow::NUM_SEVERITIES",
+        "_TF_LOG_INFO",
+        "_TF_LOG_WARNING",
+        "_TF_LOG_ERROR",
+        "_TF_LOG_FATAL",
+        "_TF_LOG_QFATAL").skip());
   }
 }

From 8f8aadc04d240dcc41def69e134ddd8020a769f4 Mon Sep 17 00:00:00 2001
From: Ryan Nett <rnett@calpoly.edu>
Date: Sat, 26 Jun 2021 18:16:18 -0700
Subject: [PATCH 2/3] Avoid string_view

Signed-off-by: Ryan Nett <rnett@calpoly.edu>
---
 .../tensorflow/internal/c_api/TFLogEntry.java | 15 +----
 .../internal/c_api/presets/tensorflow.java    | 62 +++++++++++--------
 2 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
index 13514222b89..7835d15a8a4 100644
--- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
@@ -21,23 +21,10 @@ public class TFLogEntry extends Pointer {
     /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
     public TFLogEntry(Pointer p) { super(p); }
 
-  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, message); }
-  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message);
-  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, message); }
-  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String message);
-
-  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line,
-                        @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, fname, line, message); }
-  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line,
-                        @StdString @Cast({"char*", "std::string&&"}) BytePointer message);
-  public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line,
-                        @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, fname, line, message); }
-  private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line,
-                        @StdString @Cast({"char*", "std::string&&"}) String message);
 
   public native @Cast("absl::LogSeverity") int log_severity();
   public native @StdString @Cast({"char*", "std::string&&"}) BytePointer FName();
   public native int Line();
   public native @StdString @Cast({"char*", "std::string&&"}) BytePointer ToString();
-  public native @StdString @Cast({"char*", "std::string&&"}) BytePointer text_message();
+  public native @StdString @Cast({"", "", "std::string"}) BytePointer text_message();
 }
diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
index 8eaec809863..c2befde86f5 100644
--- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
+++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
@@ -403,33 +403,43 @@ public void map(InfoMap infoMap) {
                 .cast()
                 .valueTypes("long")
                 .pointerTypes("LongPointer", "long[]"))
-        .put(new Info("absl::string_view", "absl::lts_2020_09_23::string_view", "string", "std::string", "tensorflow::string").annotations("@StdString")
+        .put(new Info("string", "std::string", "tensorflow::string").annotations("@StdString")
             .valueTypes("@Cast({\"char*\", \"std::string&&\"}) BytePointer", "@Cast({\"char*\", \"std::string&&\"}) String")
             .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer"))
-    .put(new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity").cast().valueTypes("int").pointerTypes("IntPointer", "int[]"))
-    .put(new Info("tensorflow::internal::LogEveryNSecState",
-        "tensorflow::internal::LogEveryNState",
-        "tensorflow::internal::LogEveryPow2State",
-        "tensorflow::internal::LogFirstNState",
-        "tensorflow::internal::Voidifier",
-        "tensorflow::internal::LogMessage",
-        "tensorflow::internal::LogMessageFatal",
-        "tensorflow::internal::LogMessageNull",
-        "tensorflow::internal::CheckOpMessageBuilder",
-        "tensorflow::internal::CheckOpString",
-        "tensorflow::internal::GetReferenceableValue",
-        "DVLOG",
-        "absl::LogSeverities").skip())
-    .put(new Info(
-        "tensorflow::INFO",
-        "tensorflow::WARNING",
-        "tensorflow::ERROR",
-        "tensorflow::FATAL",
-        "tensorflow::NUM_SEVERITIES",
-        "_TF_LOG_INFO",
-        "_TF_LOG_WARNING",
-        "_TF_LOG_ERROR",
-        "_TF_LOG_FATAL",
-        "_TF_LOG_QFATAL").skip());
+        .put(
+            new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity")
+                .cast()
+                .valueTypes("int")
+                .pointerTypes("IntPointer", "int[]"))
+        .put(new Info("tensorflow::TFLogEntry").purify())
+        .put(
+            new Info(
+                    "tensorflow::internal::LogEveryNSecState",
+                    "tensorflow::internal::LogEveryNState",
+                    "tensorflow::internal::LogEveryPow2State",
+                    "tensorflow::internal::LogFirstNState",
+                    "tensorflow::internal::Voidifier",
+                    "tensorflow::internal::LogMessage",
+                    "tensorflow::internal::LogMessageFatal",
+                    "tensorflow::internal::LogMessageNull",
+                    "tensorflow::internal::CheckOpMessageBuilder",
+                    "tensorflow::internal::CheckOpString",
+                    "tensorflow::internal::GetReferenceableValue",
+                    "DVLOG",
+                    "absl::LogSeverities")
+                .skip())
+        .put(
+            new Info(
+                    "tensorflow::INFO",
+                    "tensorflow::WARNING",
+                    "tensorflow::ERROR",
+                    "tensorflow::FATAL",
+                    "tensorflow::NUM_SEVERITIES",
+                    "_TF_LOG_INFO",
+                    "_TF_LOG_WARNING",
+                    "_TF_LOG_ERROR",
+                    "_TF_LOG_FATAL",
+                    "_TF_LOG_QFATAL")
+                .skip());
   }
 }

From c098372ae55f23eb466a9533cffc5de804a1d9a3 Mon Sep 17 00:00:00 2001
From: Ryan Nett <rnett@calpoly.edu>
Date: Sat, 26 Jun 2021 19:57:57 -0700
Subject: [PATCH 3/3] Working prototype

Signed-off-by: Ryan Nett <rnett@calpoly.edu>
---
 tensorflow-core/tensorflow-core-api/pom.xml   | 11 ++++
 .../annotations/org/tensorflow/op/Ops.java    |  6 +-
 .../tensorflow/internal/c_api/TFLogEntry.java |  2 +-
 .../tensorflow/internal/c_api/TFLogSink.java  | 16 +++++-
 .../java/org/tensorflow/NativeLogSink.java    | 57 +++++++++++++++++++
 .../main/java/org/tensorflow/TensorFlow.java  |  9 +++
 .../internal/c_api/presets/tensorflow.java    | 18 +++++-
 tensorflow-framework/pom.xml                  |  6 ++
 8 files changed, 116 insertions(+), 9 deletions(-)
 create mode 100644 tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java

diff --git a/tensorflow-core/tensorflow-core-api/pom.xml b/tensorflow-core/tensorflow-core-api/pom.xml
index fd96cca67fd..fbbf81e458e 100644
--- a/tensorflow-core/tensorflow-core-api/pom.xml
+++ b/tensorflow-core/tensorflow-core-api/pom.xml
@@ -47,6 +47,11 @@
       <artifactId>ndarray</artifactId>
       <version>${ndarray.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.31</version>
+    </dependency>
     <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-api</artifactId>
@@ -73,6 +78,12 @@
       <artifactId>jmh-generator-annprocess</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <version>1.7.31</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <profiles>
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java
index 7abb451be2d..c8b7ef1f873 100644
--- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java
+++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java
@@ -376,10 +376,10 @@ public final class Ops {
 
   public final SignalOps signal;
 
-  public final QuantizationOps quantization;
-
   public final TrainOps train;
 
+  public final QuantizationOps quantization;
+
   private final Scope scope;
 
   private Ops(Scope scope) {
@@ -402,8 +402,8 @@ private Ops(Scope scope) {
     math = new MathOps(this);
     audio = new AudioOps(this);
     signal = new SignalOps(this);
-    quantization = new QuantizationOps(this);
     train = new TrainOps(this);
+    quantization = new QuantizationOps(this);
   }
 
   /**
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
index 7835d15a8a4..d0afe9368d8 100644
--- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java
@@ -26,5 +26,5 @@ public class TFLogEntry extends Pointer {
   public native @StdString @Cast({"char*", "std::string&&"}) BytePointer FName();
   public native int Line();
   public native @StdString @Cast({"char*", "std::string&&"}) BytePointer ToString();
-  public native @StdString @Cast({"", "", "std::string"}) BytePointer text_message();
+  
 }
diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java
index 456b6dbbbd8..9e260ebc5d8 100644
--- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java
+++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java
@@ -12,8 +12,20 @@
 @Namespace("tensorflow") @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class)
 public class TFLogSink extends Pointer {
     static { Loader.load(); }
+    /** Default native constructor. */
+    public TFLogSink() { super((Pointer)null); allocate(); }
+    /** Native array allocator. Access with {@link Pointer#position(long)}. */
+    public TFLogSink(long size) { super((Pointer)null); allocateArray(size); }
     /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
     public TFLogSink(Pointer p) { super(p); }
+    private native void allocate();
+    private native void allocateArray(long size);
+    @Override public TFLogSink position(long position) {
+        return (TFLogSink)super.position(position);
+    }
+    @Override public TFLogSink getPointer(long i) {
+        return new TFLogSink(this).position(position + i);
+    }
 
 
   // `Send` is called synchronously during the log statement.  The logging
@@ -24,7 +36,7 @@ public class TFLogSink extends Pointer {
   // `e` is guaranteed to remain valid until the subsequent call to
   // `WaitTillSent` completes, so implementations may store a pointer to or
   // copy of `e` (e.g. in a thread local variable) for use in `WaitTillSent`.
-  public native void Send(@Const @ByRef TFLogEntry entry);
+  @Virtual(true) public native void Send(@Const @ByRef TFLogEntry entry);
 
   // `WaitTillSent` blocks the calling thread (the thread that generated a log
   // message) until the sink has finished processing the log message.
@@ -34,5 +46,5 @@ public class TFLogSink extends Pointer {
   // The default implementation returns immediately.  Like `Send`,
   // implementations should be careful not to call `LOG` or `CHECK or take any
   // locks that might be held by the `LOG` caller, to avoid deadlock.
-  public native void WaitTillSent();
+  @Virtual public native void WaitTillSent();
 }
diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java
new file mode 100644
index 00000000000..41a2f628af6
--- /dev/null
+++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java
@@ -0,0 +1,57 @@
+/*
+  Copyright 2021 The TensorFlow Authors. All Rights Reserved.
+
+ Licensed 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.
+ =======================================================================
+
+ */
+package org.tensorflow;
+
+import org.bytedeco.javacpp.Pointer;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tensorflow.internal.c_api.TFLogEntry;
+import org.tensorflow.internal.c_api.TFLogSink;
+import org.tensorflow.internal.c_api.global.tensorflow;
+
+public class NativeLogSink extends TFLogSink {
+  private static final ILoggerFactory factory = LoggerFactory.getILoggerFactory();
+  private static final Logger logger = LoggerFactory.getLogger(NativeLogSink.class);
+  NativeLogSink() {
+    super();
+  }
+
+  @Override
+  public void Send(TFLogEntry entry) {
+    //TODO make work, blocked by https://github.com/tensorflow/tensorflow/issues/44995#issuecomment-869091090
+    System.out.printf(
+        "Log message: Severity: %d, Fname: %s, line: %s, string: %s\n", entry.log_severity(), entry.FName().getString(), entry.Line(), entry.ToString().getString());
+//    Logger logger = factory.getLogger(entry.FName().getString());
+//    switch (entry.log_severity()){
+//      case tensorflow.kWarning:
+//        logger.warn(entry.ToString().getString());
+//        break;
+//      case tensorflow.kError:
+//      case tensorflow.kFatal:
+//        logger.error(entry.ToString().getString());
+//        break;
+//      default:
+//        logger.info(entry.ToString().getString());
+//    }
+  }
+
+  @Override
+  public void WaitTillSent() {
+  }
+}
diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java
index 23f4c62bc7f..4f823660d79 100644
--- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java
+++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java
@@ -15,6 +15,7 @@
  */
 package org.tensorflow;
 
+import static org.tensorflow.internal.c_api.global.tensorflow.TFAddLogSink;
 import static org.tensorflow.internal.c_api.global.tensorflow.TF_DeleteBuffer;
 import static org.tensorflow.internal.c_api.global.tensorflow.TF_DeleteLibraryHandle;
 import static org.tensorflow.internal.c_api.global.tensorflow.TF_GetAllOpList;
@@ -96,6 +97,13 @@ public static OpList loadLibrary(String filename) {
     }
   }
 
+  @SuppressWarnings("FieldCanBeLocal")
+  private static NativeLogSink sink;
+  private static void setupLogger(){
+    sink = new NativeLogSink();
+    TFAddLogSink(sink);
+  }
+
   private static TF_Library libraryLoad(String filename) {
     try (PointerScope scope = new PointerScope()) {
       TF_Status status = TF_Status.newStatus();
@@ -137,5 +145,6 @@ private TensorFlow() {}
       e.printStackTrace();
       throw e;
     }
+    setupLogger();
   }
 }
diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
index c2befde86f5..a2ac124d58b 100644
--- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
+++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java
@@ -403,15 +403,27 @@ public void map(InfoMap infoMap) {
                 .cast()
                 .valueTypes("long")
                 .pointerTypes("LongPointer", "long[]"))
-        .put(new Info("string", "std::string", "tensorflow::string").annotations("@StdString")
-            .valueTypes("@Cast({\"char*\", \"std::string&&\"}) BytePointer", "@Cast({\"char*\", \"std::string&&\"}) String")
-            .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer"))
+        .put(
+            new Info("string", "std::string", "tensorflow::string")
+                .annotations("@StdString")
+                .valueTypes(
+                    "@Cast({\"char*\", \"std::string&&\"}) BytePointer",
+                    "@Cast({\"char*\", \"std::string&&\"}) String")
+                .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer"))
+//        .put(
+//            new Info("absl::string_view")
+//                .annotations("@StdString")
+//                .valueTypes(
+//                    "@Cast({\"char*\", \"std::string&&\", \"std::string\"}) BytePointer",
+//                    "@Cast({\"char*\", \"std::string&&\", \"std::string\"}) String"))
         .put(
             new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity")
                 .cast()
                 .valueTypes("int")
                 .pointerTypes("IntPointer", "int[]"))
         .put(new Info("tensorflow::TFLogEntry").purify())
+        .put(new Info("tensorflow::TFLogSink").virtualize())
+        .put(new Info("tensorflow::TFLogEntry::text_message").skip())
         .put(
             new Info(
                     "tensorflow::internal::LogEveryNSecState",
diff --git a/tensorflow-framework/pom.xml b/tensorflow-framework/pom.xml
index af7f47815d5..ac4c24f774d 100644
--- a/tensorflow-framework/pom.xml
+++ b/tensorflow-framework/pom.xml
@@ -64,6 +64,12 @@
       <artifactId>jmh-generator-annprocess</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <version>1.7.31</version>
+      <scope>test</scope>
+    </dependency>
     <!-- Include native binaries dependencies only for testing -->
     <dependency>
       <groupId>org.tensorflow</groupId>