1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <algorithm>
6#include <iostream>
7
8#include "flutter/fml/build_config.h"
9#include "flutter/fml/log_settings.h"
10#include "flutter/fml/logging.h"
11
12#if defined(OS_ANDROID)
13#include <android/log.h>
14#elif defined(OS_IOS)
15#include <syslog.h>
16#endif
17
18namespace fml {
19namespace {
20
21const char* const kLogSeverityNames[LOG_NUM_SEVERITIES] = {"INFO", "WARNING",
22 "ERROR", "FATAL"};
23
24const char* GetNameForLogSeverity(LogSeverity severity) {
25 if (severity >= LOG_INFO && severity < LOG_NUM_SEVERITIES) {
26 return kLogSeverityNames[severity];
27 }
28 return "UNKNOWN";
29}
30
31const char* StripDots(const char* path) {
32 while (strncmp(path, "../", 3) == 0) {
33 path += 3;
34 }
35 return path;
36}
37
38const char* StripPath(const char* path) {
39 auto* p = strrchr(path, '/');
40 if (p) {
41 return p + 1;
42 }
43 return path;
44}
45
46} // namespace
47
48LogMessage::LogMessage(LogSeverity severity,
49 const char* file,
50 int line,
51 const char* condition)
52 : severity_(severity), file_(file), line_(line) {
53 stream_ << "[";
54 if (severity >= LOG_INFO) {
55 stream_ << GetNameForLogSeverity(severity);
56 } else {
57 stream_ << "VERBOSE" << -severity;
58 }
59 stream_ << ":" << (severity > LOG_INFO ? StripDots(file_) : StripPath(file_))
60 << "(" << line_ << ")] ";
61
62 if (condition) {
63 stream_ << "Check failed: " << condition << ". ";
64 }
65}
66
67LogMessage::~LogMessage() {
68 stream_ << std::endl;
69
70#if defined(OS_ANDROID)
71 android_LogPriority priority =
72 (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
73 switch (severity_) {
74 case LOG_INFO:
75 priority = ANDROID_LOG_INFO;
76 break;
77 case LOG_WARNING:
78 priority = ANDROID_LOG_WARN;
79 break;
80 case LOG_ERROR:
81 priority = ANDROID_LOG_ERROR;
82 break;
83 case LOG_FATAL:
84 priority = ANDROID_LOG_FATAL;
85 break;
86 }
87 __android_log_write(priority, "flutter", stream_.str().c_str());
88#elif defined(OS_IOS)
89 syslog(LOG_ALERT, "%s", stream_.str().c_str());
90#else
91 std::cerr << stream_.str();
92 std::cerr.flush();
93#endif
94
95 if (severity_ >= LOG_FATAL) {
96 abort();
97 }
98}
99
100int GetVlogVerbosity() {
101 return std::max(-1, LOG_INFO - GetMinLogLevel());
102}
103
104bool ShouldCreateLogMessage(LogSeverity severity) {
105 return severity >= GetMinLogLevel();
106}
107
108} // namespace fml
109