RDK Documentation (Open Sourced RDK Components)
logger.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2018 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 #include "logger.h"
20 #include <gst/gst.h>
21 #include <cstdarg>
22 #include <cstdlib>
23 #include <ctime>
24 #include <rtLog.h>
25 
26 /**
27  * Map LogLevel to the actual logging levels of diff. loggers.
28  */
29 template<typename T>
30 struct tLogLevelMap {
31  LogLevel from;
32  T to;
33 };
34 
35 static int sLogLevel;
36 
37 #if defined(USE_RDK_LOGGER)
38  #include "rdk_debug.h"
39 
40  static tLogLevelMap<rdk_LogLevel> levelMap[] = {
41  { FATAL_LEVEL, RDK_LOG_FATAL }
42  ,{ ERROR_LEVEL, RDK_LOG_ERROR }
43  ,{ WARNING_LEVEL, RDK_LOG_WARN }
44  ,{ METRIC_LEVEL, RDK_LOG_INFO }
45  ,{ INFO_LEVEL, RDK_LOG_INFO }
46  ,{ VERBOSE_LEVEL, RDK_LOG_DEBUG }
47  ,{ TRACE_LEVEL, RDK_LOG_TRACE1 }
48  };
49 
50 #else
51  static tLogLevelMap<const char*> levelMap[] = {
52  { FATAL_LEVEL, "Fatal" }
53  ,{ ERROR_LEVEL, "Error" }
54  ,{ WARNING_LEVEL, "Warning" }
55  ,{ METRIC_LEVEL, "Metric" }
56  ,{ INFO_LEVEL, "Info" }
57  ,{ VERBOSE_LEVEL, "Verbose" }
58  ,{ TRACE_LEVEL, "Trace" }
59  };
60 #endif
61 
62 #if defined(USE_RDK_LOGGER)
63  static rdk_LogLevel convertGstDebugLevelToRdkLogLevel(GstDebugLevel level)
64  {
65  switch (level)
66  {
67  case GST_LEVEL_ERROR :
68  return RDK_LOG_ERROR;
69  case GST_LEVEL_WARNING :
70  return RDK_LOG_WARN;
71  case GST_LEVEL_FIXME :
72  return RDK_LOG_NOTICE;
73  case GST_LEVEL_INFO :
74  return RDK_LOG_INFO;
75  case GST_LEVEL_DEBUG :
76  return RDK_LOG_DEBUG;
77  default :;
78  }
79  return RDK_LOG_TRACE1;
80  }
81 #endif
82 
83  static void gstLogFunction(GstDebugCategory*, GstDebugLevel level, const gchar*,
84  const gchar*, gint, GObject*, GstDebugMessage* message, gpointer)
85  {
86  const char* format = "[GStreamer] %s\n";
87  const gchar* text = gst_debug_message_get(message);
88 #if defined(USE_RDK_LOGGER)
89  rdk_LogLevel rll = convertGstDebugLevelToRdkLogLevel(level);
90  RDK_LOG(rll, "LOG.RDK.RMFBASE", format, text);
91 #else
92  (void)level;
93  fprintf(stdout, format, text);
94  fflush(stdout);
95 #endif
96  }
97 
98 static void rtRemoteLogHandler(rtLogLevel rtLevel, const char* file, int line, int threadId, char* message)
99 {
100  LogLevel level;
101  switch (rtLevel)
102  {
103  case RT_LOG_DEBUG: level = VERBOSE_LEVEL; break;
104  case RT_LOG_INFO: level = INFO_LEVEL; break;
105  case RT_LOG_WARN: level = WARNING_LEVEL; break;
106  case RT_LOG_ERROR: level = ERROR_LEVEL; break;
107  case RT_LOG_FATAL: level = FATAL_LEVEL; break;
108  default: level = VERBOSE_LEVEL; break;
109  }
110  if(level <= sLogLevel)
111  log(level, "rtlog", file, line, "tid(%d): %s", threadId, message);
112 }
113 
114 void log_init()
115 {
116 #if defined(USE_RDK_LOGGER)
117  rdk_logger_init("/etc/debug.ini");
118 #endif
119 
120  sLogLevel = INFO_LEVEL;
121 
122  char* value = getenv("RDKMEDIAPLAYER_LOG_LEVEL");
123  if (value != 0)
124  {
125  sLogLevel = atoi(value);
126  if(sLogLevel < FATAL_LEVEL)
127  sLogLevel = FATAL_LEVEL;
128  else if(sLogLevel > TRACE_LEVEL)
129  sLogLevel = TRACE_LEVEL;
130  }
131 
132  int rtLevel = RT_LOG_FATAL;//too noisy with anything else
133  char* value2 = getenv("RDKMEDIAPLAYER_RT_LOG_LEVEL");
134  if (value2 != 0)
135  {
136  rtLevel = atoi(value2);
137  if(rtLevel < RT_LOG_FATAL)
138  rtLevel = RT_LOG_FATAL;
139  else if(rtLevel > RT_LOG_DEBUG)
140  rtLevel = RT_LOG_DEBUG;
141  }
142  rtLogSetLogHandler(rtRemoteLogHandler);
143  rtLogSetLevel((rtLogLevel)rtLevel);
144 
145  LOG_INFO("log level=%d rt=%d", sLogLevel, rtLevel);
146 
147 
148  if (gst_debug_get_default_threshold() < GST_LEVEL_WARNING)
149  gst_debug_set_default_threshold(GST_LEVEL_WARNING);
150  gst_debug_remove_log_function(gst_debug_log_default);
151  gst_debug_add_log_function(&gstLogFunction, 0, 0);
152 }
153 
154 #define FMT_MSG_SIZE (4096)
155 
156 #if defined(USE_RDK_LOGGER)
157 
158 void log(LogLevel level,
159  const char* func,
160  const char* file,
161  int line,
162  const char* format, ...){
163 
164  // Rdklogger is backed with log4c which has its own default level
165  // for filtering messages. Therefore, we don't check level here.
166  char formatted_string[FMT_MSG_SIZE];
167  char formatted_string2[FMT_MSG_SIZE];
168  va_list argptr;
169  va_start(argptr, format);
170  vsnprintf(formatted_string, FMT_MSG_SIZE, format, argptr);
171  errno_t safec_rc =sprintf_s(formatted_string2, sizeof(formatted_string2), "%s:%s:%d %s", func,
172  basename(file),
173  line,
174  formatted_string);
175  if(safec_rc < EOK) {
176  ERR_CHK(safec_rc);
177  }
178 
179  va_end(argptr);
180 
181  // Currently, we use customized layout 'comcast_dated_nocr' in log4c.
182  // This layout doesn't have trailing carriage return, so we need
183  // to add it explicitly.
184  // Once the default layout is used, this addition should be deleted.
185  const char* log_str = (METRIC_LEVEL == level)
186  ? formatted_string
187  : formatted_string2;
188  RDK_LOG(levelMap[static_cast<int>(level)].to,
189  "LOG.RDK.RMFBASE",
190  "%s\n",
191  log_str);
192 
193  if (FATAL_LEVEL == level)
194  std::abort();
195 }
196 
197 #else
198 
199 static char* timestamp(char* buff);
200 
201 void log(LogLevel level,
202  const char* func,
203  const char* file,
204  int line,
205  const char* format, ...){
206 
207  if (sLogLevel >= level) {
208 
209  char formatted_string[FMT_MSG_SIZE];
210  va_list argptr;
211  va_start(argptr, format);
212  vsnprintf(formatted_string, FMT_MSG_SIZE, format, argptr);
213  va_end(argptr);
214 
215  char buff[0xFF] = {0};
216  fprintf(stdout, "%s [%s] %s:%s:%d %s",
217  timestamp(buff),
218  levelMap[static_cast<int>(level)].to,
219  func, basename(file), line,
220  formatted_string);
221 
222  fprintf(stdout, "\n");
223  fflush(stdout);
224 
225  if (FATAL_LEVEL == level)
226  std::abort();
227  }
228 }
229 
230 static char* timestamp(char* buff) {
231  struct timespec spec;
232  struct tm tm;
233 
234  clock_gettime(CLOCK_REALTIME, &spec);
235  gmtime_r(&spec.tv_sec, &tm);
236  long ms = spec.tv_nsec / 1.0e6;
237 
238  errno_t safec_rc = sprintf_s(buff,0xFF, "%02d%02d%02d-%02d:%02d:%02d.%03ld",
239  tm.tm_year + (1900-2000),
240  tm.tm_mon + 1,
241  tm.tm_mday,
242  tm.tm_hour,
243  tm.tm_min,
244  tm.tm_sec,
245  ms);
246  if(safec_rc < EOK) {
247  ERR_CHK(safec_rc);
248  }
249 
250  return buff;
251 }
252 
253 #endif
rdk_debug.h
tLogLevelMap
Definition: logger.cpp:30
RDK_LOG
#define RDK_LOG
Definition: rdk_debug.h:258
rdk_LogLevel
rdk_LogLevel
These values represent the logging 'levels' or 'types', they are each independent.
Definition: rdk_debug.h:157
LOG_INFO
#define LOG_INFO(AAMP_JS_OBJECT, FORMAT,...)
Definition: jsutils.h:39
rdk_logger_init
rdk_Error rdk_logger_init(const char *debugConfigFile)
Initialize the logger. Sets up the environment variable storage by parsing debug configuration file t...
Definition: rdk_logger_init.c:57