RDK Documentation (Open Sourced RDK Components)
rmh_monitor_print.c
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 2016 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 
20 #include <stdarg.h>
21 #include <pthread.h>
22 #include <sys/time.h>
23 #include "rmh_monitor.h"
24 
25 /**
26  * Declaring this global so we don't need to come up with 2K on the stack on every print. Could move this to 'app' in the future if we want.
27  */
28 #define PRINTBUF_SIZE 2048
29 static char printBuff[PRINTBUF_SIZE];
30 
31 inline
32 void RMH_Write(RMHMonitor *app, const char*buf) {
33  fputs(buf, app->out_file ? app->out_file : stdout);
34 }
35 
36 /**
37  * This is the main print function in this program. It will attempt to write 'fmt' string to stdout. It will also account for
38  * new lines and print the time and appPrefix before each line
39  */
40 void RMH_Print_Raw(RMHMonitor *app, struct timeval *time, const char*fmt, ...) {
41  struct tm* tm_info;
42  char *printString=printBuff;
43  int printSize;
44  va_list ap;
45  static bool newLine = true;
46  int i = 0;
47 
48  /* First construct the line to print and get the size */
49  va_start(ap, fmt);
50  printSize = vsnprintf(printString, PRINTBUF_SIZE, fmt, ap);
51  va_end(ap);
52 
53  /* Make sure we have something valid to print */
54  if (printSize > 0) {
55  char timeBuf[64];
56 
57  /* We have something to print, check if we need to also be printing a timestamp */
58  if (app->printTimestamp) {
59  /* Timestamp is needed, convert the timestamp we were passed to a readable string */
60  tm_info = localtime(&time->tv_sec);
61  snprintf(timeBuf, sizeof(timeBuf), "%02d.%02d.%02d %02d:%02d:%02d:%03ld ", tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday, tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec, time->tv_usec/1000);
62  }
63 
64 #if 0
65  /* If there is a specificed prefix add it to this timeBuf. Then we need only worry about a single prefix */
66  if (app->appPrefix && sizeof(timeBuf) > strlen(app->appPrefix) + strlen(timeBuf)) {
67  strcat(timeBuf, app->appPrefix);
68  }
69 #endif
70 
71  /* Walk through the entire string we were given. Only way to check for new lines */
72  while(printString[i] != '\0') {
73  if (newLine) {
74  /* This is a new line, start by printing the timestamp and prefix */
75  if (app->printTimestamp) RMH_Write(app, timeBuf);
76  if (app->appPrefix) RMH_Write(app, app->appPrefix);
77  newLine=false;
78  }
79 
80  if (printString[i] == '\n') {
81  /* We found a new line. Replace the next character with a temporary terminator and
82  print the string out. After printing, put the replaced character back where we
83  found it. Note, if this is the last line we'll just be replacing \0 with another
84  \0 so it should be safe */
85  char tmp=printString[i+1];
86  printString[i+1]='\0';
87  RMH_Write(app, printString);
88  printString[i+1]=tmp;
89 
90  /* Move the start of the string forward to after the newline and set the newline flag */
91  printString=&printString[i+1];
92  newLine=true;
93  i=0;
94  }
95  else {
96  /* Not a newline, move to the next character */
97  i++;
98  }
99  }
100 
101  /* We've found the end of the string. If there some string remaining, print it */
102  if (i > 0)
103  RMH_Write(app, printString);
104 
105  /* If we were limited by our buffer size inform the user. We still need to reset newline here since it's static */
106  if (printSize >= PRINTBUF_SIZE) {
107  RMH_Write(app, "\nLog message truncated\n");
108  newLine=true;
109  }
110  }
111  else if (printSize < 0 ) {
112  /* This should never happen. But if it does we still need to reset newline here since it's static */
113  RMH_Write(app, "\nInternal print error\n");
114  newLine=true;
115  }
116 
117  fflush(stdout);
118 }
RMHMonitor
Definition: rmh_monitor.h:77