1 // Copyright 2022 The Android Open Source Project
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 #include "log.h"
15 
16 #include <chrono>
17 #include <cstdarg>
18 #include <cstdio>
19 #include <ctime>
20 #include <fstream>
21 
22 namespace netsim {
23 
BtsLogDefault(int priority,const char * file,int lineNumber,const char * buffer)24 void BtsLogDefault(int priority, const char *file, int lineNumber,
25                    const char *buffer) {
26   auto now = std::chrono::system_clock::now();
27   auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
28   auto now_t = std::chrono::system_clock::to_time_t(now);
29   //"mm-dd_HH:MM:SS.sss\0" is 19 byte long
30   char prefix[19];
31   auto l = std::strftime(prefix, sizeof(prefix), "%m-%d %H:%M:%S",
32                          std::gmtime(&now_t));
33   snprintf(prefix + l, sizeof(prefix) - l, ".%03u",
34            static_cast<unsigned int>(now_ms.time_since_epoch().count() % 1000));
35 
36   // Obtain the file name from given filepath
37   std::string file_path(file);
38   const char *separators = "/";
39 #ifdef _WIN32
40   separators = "\\";
41 #endif
42   size_t last_slash_pos = file_path.find_last_of(separators);
43   if (last_slash_pos != std::string::npos) {
44     file_path = file_path.substr(last_slash_pos + 1);
45   }
46 
47   // Obtain the log level based on given priority
48   std::string level;
49   switch (priority) {
50     case 0:
51       level = "E";
52       break;
53     case 1:
54       level = "W";
55       break;
56     case 2:
57       level = "I";
58       break;
59     default:
60       level = "D";
61   }
62 
63   fprintf(stderr, "netsimd %s %s %s:%d - %s\n", level.c_str(), prefix,
64           file_path.c_str(), lineNumber, buffer);
65   fflush(stderr);
66 }
67 
68 static BtsLogFn logFunction = BtsLogDefault;
69 
__BtsLog(int priority,const char * file,int line,const char * fmt,...)70 void __BtsLog(int priority, const char *file, int line, const char *fmt, ...) {
71   char buffer[255];
72   va_list arglist;
73 
74   va_start(arglist, fmt);
75   vsnprintf(buffer, sizeof(buffer), fmt, arglist);
76   va_end(arglist);
77 
78   logFunction(priority, file, line, buffer);
79 }
80 
setBtsLogSink(BtsLogFn logFn)81 void setBtsLogSink(BtsLogFn logFn) { logFunction = logFn; }
82 }  // namespace netsim
83