• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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