RDK Documentation (Open Sourced RDK Components)
aamplogging.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license 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 
20 /**
21  * @file aamplogging.cpp
22  * @brief AAMP logging mechanisum source file
23  */
24 
25 #include <iomanip>
26 #include <algorithm>
27 #include "priv_aamp.h"
28 using namespace std;
29 
30 #ifdef USE_SYSLOG_HELPER_PRINT
31 #include "syslog_helper_ifc.h"
32 #endif
33 #ifdef USE_SYSTEMD_JOURNAL_PRINT
34 #include <systemd/sd-journal.h>
35 #endif
36 
37 /**
38  * @brief Log file and cfg directory path - To support dynamic directory configuration
39  */
40 static char gAampLog[] = "./aamp.log";
41 static char gAampCfg[] = "/opt/aamp.cfg";
42 static char gAampCliCfg[] = "/opt/aampcli.cfg";
43 
44 /*-----------------------------------------------------------------------------------------------------*/
45 bool AampLogManager::disableLogRedirection = false;
46 
47 /**
48  * @brief To check the given log level is allowed to print mechanism
49  */
51 {
52  return (chkLevel>=aampLoglevel);
53 }
54 
55 /**
56  * @brief Set the log level for print mechanism
57  */
59 {
60  if(!info && !debug && !trace)
61  aampLoglevel = newLevel;
62 }
63 
64 /**
65  * @brief Set log file and cfg directory index.
66  */
68 {
69  gAampLog[0] = driveName;
70  gAampCfg[0] = driveName;
71  gAampCliCfg[0] = driveName;
72 }
73 
74 /**
75  * @brief Get aamp cfg directory.
76  */
78 {
79  return gAampCfg;
80 }
81 
82 /**
83  * @brief Get aampcli cfg directory.
84  */
86 {
87  return gAampCliCfg;
88 }
89 
90 /**
91  * @brief Get a hex string representation of a vector of bytes
92  */
93 std::string AampLogManager::getHexDebugStr(const std::vector<uint8_t>& data)
94 {
95  std::ostringstream hexSs;
96  hexSs << "0x";
97  hexSs << std::hex << std::uppercase << std::setfill('0');
98  std::for_each(data.cbegin(), data.cend(), [&](int c) { hexSs << std::setw(2) << c; });
99  return hexSs.str();
100 }
101 
102 /**
103  * @brief Print the network latency level logging for triage purpose
104  */
105 void AampLogManager::LogNetworkLatency(const char* url, int downloadTime, int downloadThresholdTimeoutMs, MediaType type)
106 {
107  std::string contentType;
108  std::string location;
109  std::string symptom;
110 
111  ParseContentUrl(url, contentType, location, symptom, type);
112 
113  AAMPLOG(this, eLOGLEVEL_WARN, "WARN", "AAMPLogNetworkLatency downloadTime=%d downloadThreshold=%d type='%s' location='%s' symptom='%s' url='%s'",
114  downloadTime, downloadThresholdTimeoutMs, contentType.c_str(), location.c_str(), symptom.c_str(), url);
115 }
116 
117 /**
118  * @brief Print the network error level logging for triage purpose
119  */
120 void AampLogManager::LogNetworkError(const char* url, AAMPNetworkErrorType errorType, int errorCode, MediaType type)
121 {
122  std::string contentType;
123  std::string location;
124  std::string symptom;
125 
126  ParseContentUrl(url, contentType, location, symptom, type);
127 
128  switch(errorType)
129  {
131  {
132  if(errorCode >= 400)
133  {
134  AAMPLOG(this, eLOGLEVEL_ERROR, "ERROR", "AAMPLogNetworkError error='http error %d' type='%s' location='%s' symptom='%s' url='%s'",
135  errorCode, contentType.c_str(), location.c_str(), symptom.c_str(), url );
136  }
137  }
138  break; /*AAMPNetworkErrorHttp*/
139 
141  {
142  if(errorCode > 0)
143  {
144  AAMPLOG(this, eLOGLEVEL_ERROR, "ERROR", "AAMPLogNetworkError error='timeout %d' type='%s' location='%s' symptom='%s' url='%s'",
145  errorCode, contentType.c_str(), location.c_str(), symptom.c_str(), url );
146  }
147  }
148  break; /*AAMPNetworkErrorTimeout*/
149 
151  {
152  if(errorCode > 0)
153  {
154  AAMPLOG(this, eLOGLEVEL_ERROR, "ERROR", "AAMPLogNetworkError error='curl error %d' type='%s' location='%s' symptom='%s' url='%s'",
155  errorCode, contentType.c_str(), location.c_str(), symptom.c_str(), url );
156  }
157  }
158  break; /*AAMPNetworkErrorCurl*/
159 
161  break;
162  }
163 }
164 
165 
166 /**
167  * @brief To get the issue symptom based on the error type for triage purpose
168  */
169 void AampLogManager::ParseContentUrl(const char* url, std::string& contentType, std::string& location, std::string& symptom, MediaType type)
170 {
171  static const char *mMediaTypes[eMEDIATYPE_DEFAULT] = { // enum MediaType
172  "VIDEO",
173  "AUDIO",
174  "SUBTITLE",
175  "AUX-AUDIO",
176  "MANIFEST",
177  "LICENCE",
178  "IFRAME",
179  "INIT_VIDEO",
180  "INIT_AUDIO",
181  "INIT_SUBTITLE",
182  "INIT_AUX-AUDIO",
183  "PLAYLIST_VIDEO",
184  "PLAYLIST_AUDIO",
185  "PLAYLIST_SUBTITLE",
186  "PLAYLIST_AUX-AUDIO",
187  "PLAYLIST_IFRAME",
188  "INIT_IFRAME"};
189 
190  if (type < eMEDIATYPE_DEFAULT)
191  {
192  contentType = mMediaTypes[type];
193  }
194  else
195  {
196  contentType = "unknown";
197  }
198 
199  switch (type)
200  {
201  case eMEDIATYPE_MANIFEST:
202  {
203  symptom = "video fails to start, has delayed start or freezes/buffers";
204  }
205  break;
206 
210  {
211  symptom = "video fails to start or freeze/buffering";
212  }
213  break;
214 
218  {
219  symptom = "video fails to start";
220  }
221  break;
222 
223  case eMEDIATYPE_VIDEO:
224  {
225  symptom = "freeze/buffering";
226  }
227  break;
228 
229  case eMEDIATYPE_AUDIO:
230  {
231  symptom = "audio drop or freeze/buffering";
232  }
233  break;
234 
235  case eMEDIATYPE_IFRAME:
236  {
237  symptom = "trickplay ends or freezes";
238  }
239  break;
240 
241  default:
242  symptom = "unknown";
243  break;
244  }
245 
246  if(strstr(url,"//mm."))
247  {
248  location = "manifest manipulator";
249  }
250  else if(strstr(url,"//odol"))
251  {
252  location = "edge cache";
253  }
254  else if(strstr(url,"127.0.0.1:9080"))
255  {
256  location = "fog";
257  }
258  else
259  {
260  location = "unknown";
261  }
262 }
263 
264 /**
265  * @brief Print the DRM error level logging for triage purpose
266  */
267 void AampLogManager::LogDRMError(int major, int minor)
268 {
269  std::string description;
270 
271  switch(major)
272  {
273  case 3307: /* Internal errors */
274  {
275  if(minor == 268435462)
276  {
277  description = "Missing drm keys. Files are missing from /opt/drm. This could happen if socprovisioning fails to pull keys from fkps. This could also happen with a new box type that isn't registered with fkps. Check the /opt/logs/socprov.log for error. Contact ComSec for help.";
278  }
279  else if(minor == 570425352)
280  {
281  description = "Stale cache data. There is bad data in adobe cache at /opt/persistent/adobe. This can happen if the cache isn't cleared by /lib/rdk/cleanAdobe.sh after either an FKPS key update or a firmware update. This should not be happening in the field. For engineers, they can try a factory reset to fix the problem.";
282  }
283  else if(minor == 1000022)
284  {
285  description = "Local cache directory not readable. The Receiver running as non-root cannot access and read the adobe cache at /opt/persistent/adobe. This can happen if /lib/rdk/prepareChrootEnv.sh fails to set that folders privileges. Run ls -l /opt/persistent and check the access rights. Contact the SI team for help. Also see jira XRE-6687";
286  }
287  }
288  break; /* 3307 */
289 
290  case 3321: /* Individualization errors */
291  {
292  if(minor == 102)
293  {
294  description = "Invalid signiture request on the Adobe individualization request. Expired certs can cause this, so the first course of action is to verify if the certs, temp baked in or production fkps, have not expired.";
295  }
296  else if(minor == 10100)
297  {
298  description = "Unknown Device class error from the Adobe individualization server. The drm certs may be been distributed to MSO security team for inclusion in fkps, but Adobe has not yet added the device info to their indi server.";
299  }
300  else if(minor == 1107296357)
301  {
302  description = "Failed to connect to individualization server. This can happen if the network goes down. This can also happen if bad proxy settings exist in /opt/xreproxy.conf. Check the receiver.log for the last HttpRequestBegin before the error occurs and check the host name in the url, then check your proxy conf";
303  }
304 
305  if(minor == 1000595) /* RequiredSPINotAvailable */
306  {
307  /* This error doesn't tell us anything useful but points to some other underlying issue.
308  * Don't report this error. Ensure a triage log is being create for the underlying issue
309  */
310 
311  return;
312  }
313  }
314  break; /* 3321 */
315 
316  case 3322: /* Device binding failure */
317  {
318  description = "Device binding failure. DRM data cached by the player at /opt/persistent/adobe, may be corrupt, missing, or innaccesible due to file permision. Please check this folder. A factory reset may be required to fix this and force a re-individualization of the box to reset that data.";
319  }
320  break; /* 3322 */
321 
322  case 3328:
323  {
324  if(minor == 1003532)
325  {
326  description = "Potential server issue. This could happen if drm keys are missing or bad. To attempt a quick fix: Back up /opt/drm and /opt/persistent/adobe, perform a factory reset, and see if that fixes the issue. Reach out to ComSec team for help diagnosing the error.";
327  }
328  }
329  break; /* 3328 */
330 
331  case 3329: /* Application errors (our consec errors) */
332  {
333  description = "MSO license server error response. This could happen for various reasons: bad cache data, bad session token, any license related issue. To attempt a quick fix: Back up /opt/drm and /opt/persistent/adobe, perform a factory reset, and see if that fixes the issue. Reach out to ComSec team for help diagnosing the error.";
334  }
335  break; /* 3329 */
336 
337  case 3338: /* Unknown connection type */
338  {
339  description = "Unknown connection type. Rare issue related to output protection code not being implemented on certain branches or core or for new socs. See STBI-6542 for details. Reach out to Receiver IP-Video team for help.";
340  }
341  break; /* 3338 */
342  }
343 
344  if(description.empty())
345  {
346  description = "Unrecognized error. Please report this to the STB IP-Video team.";
347  }
348 
349  AAMPLOG(this, eLOGLEVEL_ERROR, "ERROR", "AAMPLogDRMError error=%d.%d description='%s'", major, minor, description.c_str());
350 }
351 
352 /**
353  * @brief Log ABR info for triage purpose
354  */
356 {
357  if (pstAbrInfo)
358  {
359  std::string reason;
360  std::string profile;
361  std::string symptom;
362 
363  if (pstAbrInfo->desiredBandwidth > pstAbrInfo->currentBandwidth)
364  {
365  profile = "higher";
366  symptom = "video quality may increase";
367  }
368  else
369  {
370  profile = "lower";
371  symptom = "video quality may decrease";
372  }
373 
374  switch(pstAbrInfo->abrCalledFor)
375  {
376  case AAMPAbrBandwidthUpdate:
377  {
378  reason = (pstAbrInfo->desiredBandwidth > pstAbrInfo->currentBandwidth) ? "bandwidth is good enough" : "not enough bandwidth";
379  }
380  break; /* AAMPAbrBandwidthUpdate */
381 
382  case AAMPAbrManifestDownloadFailed:
383  {
384  reason = "manifest download failed'";
385  }
386  break; /* AAMPAbrManifestDownloadFailed */
387 
388  case AAMPAbrFragmentDownloadFailed:
389  {
390  reason = "fragment download failed'";
391  }
392  break; /* AAMPAbrFragmentDownloadFailed */
393 
394  case AAMPAbrUnifiedVideoEngine:
395  {
396  reason = "changed based on unified video engine user preferred bitrate";
397  }
398  break; /* AAMPAbrUserRequest */
399  }
400 
401  if(pstAbrInfo->errorType == AAMPNetworkErrorHttp)
402  {
403  reason += " error='http error ";
404  reason += to_string(pstAbrInfo->errorCode);
405  symptom += " (or) freeze/buffering";
406  }
407 
408  AAMPLOG(this, eLOGLEVEL_WARN, "WARN", "AAMPLogABRInfo : switching to '%s' profile '%d -> %d' currentBandwidth[%ld]->desiredBandwidth[%ld] nwBandwidth[%ld] reason='%s' symptom='%s'",
409  profile.c_str(), pstAbrInfo->currentProfileIndex, pstAbrInfo->desiredProfileIndex, pstAbrInfo->currentBandwidth,
410  pstAbrInfo->desiredBandwidth, pstAbrInfo->networkBandwidth, reason.c_str(), symptom.c_str());
411  }
412 }
413 
414 /**
415  * @brief Check curl error before log on console
416  */
418 {
419  bool returnValue = false;
420 
421  if ((errorCode !=0) && (errorCode != CURLE_WRITE_ERROR) && (errorCode != CURLE_ABORTED_BY_CALLBACK))
422  {
423  returnValue = true;
424  }
425 
426  return returnValue;
427 }
428 
429 /**
430  * @brief Print logs to console / log fil
431  */
432 void logprintf(const char *format, ...)
433 {
434  int len = 0;
435  va_list args;
436  va_start(args, format);
437 
438  char gDebugPrintBuffer[MAX_DEBUG_LOG_BUFF_SIZE];
439  len = snprintf(gDebugPrintBuffer, sizeof(gDebugPrintBuffer), "[AAMP-PLAYER]");
440  vsnprintf(gDebugPrintBuffer+len, MAX_DEBUG_LOG_BUFF_SIZE-len, format, args);
441  gDebugPrintBuffer[(MAX_DEBUG_LOG_BUFF_SIZE-1)] = 0;
442 
443  va_end(args);
444 
445 #if (defined (USE_SYSTEMD_JOURNAL_PRINT) || defined (USE_SYSLOG_HELPER_PRINT))
446  if(!AampLogManager::disableLogRedirection)
447  {
448 #ifdef USE_SYSTEMD_JOURNAL_PRINT
449  sd_journal_print(LOG_NOTICE, "%s", gDebugPrintBuffer);
450 #else
451  send_logs_to_syslog(gDebugPrintBuffer);
452 #endif
453  }
454  else
455  {
456  struct timeval t;
457  gettimeofday(&t, NULL);
458  printf("%ld:%3ld : %s\n", (long int)t.tv_sec, (long int)t.tv_usec / 1000, gDebugPrintBuffer);
459  }
460 #else //USE_SYSTEMD_JOURNAL_PRINT
461 #ifdef AAMP_SIMULATOR_BUILD
462  static bool init;
463 
464  FILE *f = fopen(gAampLog, (init ? "a" : "w"));
465  if (f)
466  {
467  init = true;
468  fputs(gDebugPrintBuffer, f);
469  fclose(f);
470  }
471 
472  struct timeval t;
473  gettimeofday(&t, NULL);
474  printf("%ld:%3ld : %s\n", (long int)t.tv_sec, (long int)t.tv_usec / 1000, gDebugPrintBuffer);
475 #endif
476 #endif
477 }
478 
479 /**
480  * @brief Print logs to console / log file
481  */
482 void logprintf_new(int playerId,const char* levelstr,const char* file, int line,const char *format, ...)
483 {
484  int len = 0;
485  va_list args;
486  va_start(args, format);
487 
488  char gDebugPrintBuffer[MAX_DEBUG_LOG_BUFF_SIZE];
489  len = snprintf(gDebugPrintBuffer, sizeof(gDebugPrintBuffer), "[AAMP-PLAYER][%d][%s][%s][%d]",playerId,levelstr,file,line);
490  vsnprintf(gDebugPrintBuffer+len, MAX_DEBUG_LOG_BUFF_SIZE-len, format, args);
491  gDebugPrintBuffer[(MAX_DEBUG_LOG_BUFF_SIZE-1)] = 0;
492 
493  va_end(args);
494 
495 #if (defined (USE_SYSTEMD_JOURNAL_PRINT) || defined (USE_SYSLOG_HELPER_PRINT))
496  if(!AampLogManager::disableLogRedirection)
497  {
498 #ifdef USE_SYSTEMD_JOURNAL_PRINT
499  sd_journal_print(LOG_NOTICE, "%s", gDebugPrintBuffer);
500 #else
501  send_logs_to_syslog(gDebugPrintBuffer);
502 #endif
503  }
504  else
505  {
506  struct timeval t;
507  gettimeofday(&t, NULL);
508  printf("%ld:%3ld : %s\n", (long int)t.tv_sec, (long int)t.tv_usec / 1000, gDebugPrintBuffer);
509  }
510 #else //USE_SYSTEMD_JOURNAL_PRINT
511 #ifdef AAMP_SIMULATOR_BUILD
512  static bool init;
513 
514  FILE *f = fopen(gAampLog, (init ? "a" : "w"));
515  if (f)
516  {
517  init = true;
518  fputs(gDebugPrintBuffer, f);
519  fclose(f);
520  }
521 
522  struct timeval t;
523  gettimeofday(&t, NULL);
524  printf("%ld:%3ld : %s\n", (long int)t.tv_sec, (long int)t.tv_usec / 1000, gDebugPrintBuffer);
525 #endif
526 #endif
527 }
528 
529 /**
530  * @brief Compactly log blobs of binary data
531  *
532  */
533 void DumpBlob(const unsigned char *ptr, size_t len)
534 {
535 #define FIT_CHARS 64
536  char buf[FIT_CHARS + 1]; // pad for NUL
537  char *dst = buf;
538  const unsigned char *fin = ptr+len;
539  int fit = FIT_CHARS;
540  while (ptr < fin)
541  {
542  unsigned char c = *ptr++;
543  if (c >= ' ' && c < 128)
544  { // printable ascii
545  *dst++ = c;
546  fit--;
547  }
548  else if( fit>=4 )
549  {
550  *dst++ = '[';
551  WRITE_HASCII( dst, c );
552  *dst++ = ']';
553  fit -= 4;
554  }
555  else
556  {
557  fit = 0;
558  }
559  if (fit==0 || ptr==fin )
560  {
561  *dst++ = 0x00;
562 
563  AAMPLOG_WARN("%s", buf);
564  dst = buf;
565  fit = FIT_CHARS;
566  }
567  }
568 }
569 /**
570  * @}
571 */
AAMP_LogLevel
AAMP_LogLevel
Log level's of AAMP.
Definition: AampLogManager.h:97
eMEDIATYPE_INIT_IFRAME
@ eMEDIATYPE_INIT_IFRAME
Definition: AampMediaType.h:55
eMEDIATYPE_VIDEO
@ eMEDIATYPE_VIDEO
Definition: AampMediaType.h:39
eMEDIATYPE_PLAYLIST_IFRAME
@ eMEDIATYPE_PLAYLIST_IFRAME
Definition: AampMediaType.h:54
AampLogManager::setLogAndCfgDirectory
void setLogAndCfgDirectory(char driveName)
Set log file and cfg directory index.
Definition: aamplogging.cpp:67
eMEDIATYPE_MANIFEST
@ eMEDIATYPE_MANIFEST
Definition: AampMediaType.h:43
AampLogManager::LogNetworkError
void LogNetworkError(const char *url, AAMPNetworkErrorType errorType, int errorCode, MediaType type)
Print the network error level logging for triage purpose.
Definition: aamplogging.cpp:120
DumpBlob
void DumpBlob(const unsigned char *ptr, size_t len)
Compactly log blobs of binary data.
Definition: aamplogging.cpp:533
AampLogManager::LogABRInfo
void LogABRInfo(AAMPAbrInfo *pstAbrInfo)
Log ABR info for triage purpose.
Definition: aamplogging.cpp:355
AAMPLOG
#define AAMPLOG(MYLOGOBJ, LEVEL, LEVELSTR, FORMAT,...)
Macro for validating the log level to be enabled.
Definition: AampLogManager.h:50
eMEDIATYPE_DEFAULT
@ eMEDIATYPE_DEFAULT
Definition: AampMediaType.h:58
AampLogManager::getAampCliCfgPath
const char * getAampCliCfgPath(void)
Get aampcli cfg directory.
Definition: aamplogging.cpp:85
AampLogManager::LogDRMError
void LogDRMError(int major, int minor)
Print the DRM error level logging for triage purpose.
Definition: aamplogging.cpp:267
eMEDIATYPE_AUDIO
@ eMEDIATYPE_AUDIO
Definition: AampMediaType.h:40
eMEDIATYPE_INIT_AUDIO
@ eMEDIATYPE_INIT_AUDIO
Definition: AampMediaType.h:47
eMEDIATYPE_PLAYLIST_VIDEO
@ eMEDIATYPE_PLAYLIST_VIDEO
Definition: AampMediaType.h:50
AampLogManager::LogNetworkLatency
void LogNetworkLatency(const char *url, int downloadTime, int downloadThresholdTimeoutMs, MediaType type)
Print the network latency level logging for triage purpose.
Definition: aamplogging.cpp:105
AAMPNetworkErrorHttp
@ AAMPNetworkErrorHttp
Definition: AampLogManager.h:112
MediaType
MediaType
Media types.
Definition: AampMediaType.h:37
AAMPNetworkErrorType
AAMPNetworkErrorType
Log level network error enum.
Definition: AampLogManager.h:109
AampLogManager::isLogworthyErrorCode
bool isLogworthyErrorCode(int errorCode)
Check curl error before log on console.
Definition: aamplogging.cpp:417
gAampLog
static char gAampLog[]
Log file and cfg directory path - To support dynamic directory configuration.
Definition: aamplogging.cpp:40
AampLogManager::getAampCfgPath
const char * getAampCfgPath(void)
Get aamp cfg directory.
Definition: aamplogging.cpp:77
AampLogManager::isLogLevelAllowed
bool isLogLevelAllowed(AAMP_LogLevel chkLevel)
To check the given log level is allowed to print mechanism.
Definition: aamplogging.cpp:50
eMEDIATYPE_IFRAME
@ eMEDIATYPE_IFRAME
Definition: AampMediaType.h:45
eLOGLEVEL_WARN
@ eLOGLEVEL_WARN
Definition: AampLogManager.h:101
priv_aamp.h
Private functions and types used internally by AAMP.
AAMPNetworkErrorCurl
@ AAMPNetworkErrorCurl
Definition: AampLogManager.h:114
MAX_DEBUG_LOG_BUFF_SIZE
#define MAX_DEBUG_LOG_BUFF_SIZE
Max debug log buffer size.
Definition: priv_aamp.h:114
eMEDIATYPE_INIT_VIDEO
@ eMEDIATYPE_INIT_VIDEO
Definition: AampMediaType.h:46
eLOGLEVEL_ERROR
@ eLOGLEVEL_ERROR
Definition: AampLogManager.h:102
AAMPNetworkErrorTimeout
@ AAMPNetworkErrorTimeout
Definition: AampLogManager.h:113
logprintf
void logprintf(const char *format,...)
Print logs to console / log fil.
Definition: aamplogging.cpp:432
AampLogManager::ParseContentUrl
void ParseContentUrl(const char *url, std::string &contentType, std::string &location, std::string &symptom, MediaType type)
To get the issue symptom based on the error type for triage purpose.
Definition: aamplogging.cpp:169
AampLogManager::getHexDebugStr
static std::string getHexDebugStr(const std::vector< uint8_t > &data)
Get a hex string representation of a vector of bytes.
Definition: aamplogging.cpp:93
eMEDIATYPE_PLAYLIST_AUDIO
@ eMEDIATYPE_PLAYLIST_AUDIO
Definition: AampMediaType.h:51
AAMPAbrInfo
ABR info structure.
Definition: AampLogManager.h:132
AAMPNetworkErrorNone
@ AAMPNetworkErrorNone
Definition: AampLogManager.h:111
logprintf_new
void logprintf_new(int playerId, const char *levelstr, const char *file, int line, const char *format,...)
Print logs to console / log file.
Definition: aamplogging.cpp:482
AampLogManager::setLogLevel
void setLogLevel(AAMP_LogLevel newLevel)
Set the log level for print mechanism.
Definition: aamplogging.cpp:58