1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations 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
LogMessage(const char * fname,int line,int severity)26 LogMessage::LogMessage(const char* fname, int line, int severity)
27 : fname_(fname), line_(line), severity_(severity) {}
28
GenerateLogMessage()29 void 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
69 namespace {
70
71 // Parse log level (int64) from environment variable (char*)
LogLevelStrToInt(const char * tf_env_var_val)72 int64_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
MinLogLevelFromEnv()91 int64_t MinLogLevelFromEnv() {
92 const char* tf_env_var_val = getenv("TF_CPP_MIN_LOG_LEVEL");
93 return LogLevelStrToInt(tf_env_var_val);
94 }
95
MinVLogLevelFromEnv()96 int64_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
~LogMessage()103 LogMessage::~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
MinVLogLevel()109 int64_t LogMessage::MinVLogLevel() {
110 static const int64_t min_vlog_level = MinVLogLevelFromEnv();
111 return min_vlog_level;
112 }
113
LogMessageFatal(const char * file,int line)114 LogMessageFatal::LogMessageFatal(const char* file, int line)
115 : LogMessage(file, line, ANDROID_LOG_FATAL) {}
~LogMessageFatal()116 LogMessageFatal::~LogMessageFatal() {
117 // abort() ensures we don't return (we promised we would not via
118 // ATTRIBUTE_NORETURN).
119 GenerateLogMessage();
120 abort();
121 }
122
LogString(const char * fname,int line,int severity,const std::string & message)123 void LogString(const char* fname, int line, int severity,
124 const std::string& message) {
125 LogMessage(fname, line, severity) << message;
126 }
127
LogPrintF(const int severity,const char * format,...)128 void 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