1/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 3Licensed under the Apache License, Version 2.0 (the "License"); 4you may not use this file except in compliance with the License. 5You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9Unless required by applicable law or agreed to in writing, software 10distributed under the License is distributed on an "AS IS" BASIS, 11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12See the License for the specific language governing permissions and 13limitations under the License. 14==============================================================================*/ 15 16#include "tensorflow/examples/android/jni/object_tracking/logging.h" 17 18#ifdef STANDALONE_DEMO_LIB 19 20#include <android/log.h> 21#include <stdlib.h> 22#include <time.h> 23#include <iostream> 24#include <sstream> 25 26LogMessage::LogMessage(const char* fname, int line, int severity) 27 : fname_(fname), line_(line), severity_(severity) {} 28 29void LogMessage::GenerateLogMessage() { 30 int android_log_level; 31 switch (severity_) { 32 case INFO: 33 android_log_level = ANDROID_LOG_INFO; 34 break; 35 case WARNING: 36 android_log_level = ANDROID_LOG_WARN; 37 break; 38 case ERROR: 39 android_log_level = ANDROID_LOG_ERROR; 40 break; 41 case FATAL: 42 android_log_level = ANDROID_LOG_FATAL; 43 break; 44 default: 45 if (severity_ < INFO) { 46 android_log_level = ANDROID_LOG_VERBOSE; 47 } else { 48 android_log_level = ANDROID_LOG_ERROR; 49 } 50 break; 51 } 52 53 std::stringstream ss; 54 const char* const partial_name = strrchr(fname_, '/'); 55 ss << (partial_name != nullptr ? partial_name + 1 : fname_) << ":" << line_ 56 << " " << str(); 57 __android_log_write(android_log_level, "native", ss.str().c_str()); 58 59 // Also log to stderr (for standalone Android apps). 60 std::cerr << "native : " << ss.str() << std::endl; 61 62 // Android logging at level FATAL does not terminate execution, so abort() 63 // is still required to stop the program. 64 if (severity_ == FATAL) { 65 abort(); 66 } 67} 68 69namespace { 70 71// Parse log level (int64) from environment variable (char*) 72int64_t LogLevelStrToInt(const char* tf_env_var_val) { 73 if (tf_env_var_val == nullptr) { 74 return 0; 75 } 76 77 // Ideally we would use env_var / safe_strto64, but it is 78 // hard to use here without pulling in a lot of dependencies, 79 // so we use std:istringstream instead 80 std::string min_log_level(tf_env_var_val); 81 std::istringstream ss(min_log_level); 82 int64_t level; 83 if (!(ss >> level)) { 84 // Invalid vlog level setting, set level to default (0) 85 level = 0; 86 } 87 88 return level; 89} 90 91int64_t MinLogLevelFromEnv() { 92 const char* tf_env_var_val = getenv("TF_CPP_MIN_LOG_LEVEL"); 93 return LogLevelStrToInt(tf_env_var_val); 94} 95 96int64_t MinVLogLevelFromEnv() { 97 const char* tf_env_var_val = getenv("TF_CPP_MIN_VLOG_LEVEL"); 98 return LogLevelStrToInt(tf_env_var_val); 99} 100 101} // namespace 102 103LogMessage::~LogMessage() { 104 // Read the min log level once during the first call to logging. 105 static int64_t min_log_level = MinLogLevelFromEnv(); 106 if (TF_PREDICT_TRUE(severity_ >= min_log_level)) GenerateLogMessage(); 107} 108 109int64_t LogMessage::MinVLogLevel() { 110 static const int64_t min_vlog_level = MinVLogLevelFromEnv(); 111 return min_vlog_level; 112} 113 114LogMessageFatal::LogMessageFatal(const char* file, int line) 115 : LogMessage(file, line, ANDROID_LOG_FATAL) {} 116LogMessageFatal::~LogMessageFatal() { 117 // abort() ensures we don't return (we promised we would not via 118 // ATTRIBUTE_NORETURN). 119 GenerateLogMessage(); 120 abort(); 121} 122 123void LogString(const char* fname, int line, int severity, 124 const std::string& message) { 125 LogMessage(fname, line, severity) << message; 126} 127 128void LogPrintF(const int severity, const char* format, ...) { 129 char message[1024]; 130 va_list argptr; 131 va_start(argptr, format); 132 vsnprintf(message, 1024, format, argptr); 133 va_end(argptr); 134 __android_log_write(severity, "native", message); 135 136 // Also log to stderr (for standalone Android apps). 137 std::cerr << "native : " << message << std::endl; 138} 139 140#endif 141