1 /++ 2 + Copyright: Copyright © 2017, Christian Köstlin 3 + License: MIT 4 + Authors: Christian Koestlin 5 +/ 6 7 module androidlogger; 8 9 @safe: 10 11 import std.experimental.logger; 12 public import androidlogger.packageversion; 13 14 class AndroidLogger : FileLogger 15 { 16 import std.stdio; 17 import std..string; 18 import std.concurrency; 19 import std.process; 20 import colored; 21 22 private string[LogLevel] logLevel2String; 23 private bool withColors; 24 25 this(File file = stdout, bool withColors = true, LogLevel level = LogLevel.all) @system 26 { 27 super(file, level); 28 this.withColors = withColors; 29 initLogLevel2String(); 30 } 31 32 static string tid2string(Tid id) @trusted 33 { 34 import std.conv : text; 35 36 return text(id).replace("Tid(", "").replace(")", ""); 37 } 38 39 override void writeLogMsg(ref LogEntry payload) @trusted 40 { 41 with (payload) 42 { 43 // android logoutput looks lokes this: 44 // 06-06 12:14:46.355 372 18641 D audio_hw_primary: disable_audio_route: reset and update 45 // DATE TIME PID TID LEVEL TAG Message 46 auto h = timestamp.fracSecs.split!("msecs"); 47 auto idx = msg.indexOf(':'); 48 string tag = ""; // "%s.%d".format(file, line), 49 string text = ""; 50 if (idx == -1) 51 { 52 tag = "stdout"; 53 text = msg; 54 } 55 else 56 { 57 tag = msg[0 .. idx]; 58 text = msg[idx + 1 .. $]; 59 } 60 this.file.lockingTextWriter() 61 .put(colorize("%02d-%02d %02d:%02d:%02d.%03d %d %s %s %s: %s\n".format(timestamp.month, // DATE 62 timestamp.day, timestamp.hour, // TIME 63 timestamp.minute, timestamp.second, 64 h.msecs, std.process.thisProcessID, // PID 65 tid2string(threadId), // TID 66 logLevel2String[logLevel], tag, text), logLevel).toString); 67 68 } 69 } 70 71 private void initLogLevel2String() 72 { 73 logLevel2String[LogLevel.trace] = "T"; 74 logLevel2String[LogLevel.info] = "I"; 75 logLevel2String[LogLevel.warning] = "W"; 76 logLevel2String[LogLevel.error] = "E"; 77 logLevel2String[LogLevel.critical] = "C"; 78 logLevel2String[LogLevel.fatal] = "F"; 79 } 80 81 private auto colorize(string s, LogLevel logLevel) 82 { 83 if (!withColors) 84 { 85 return s.defaultColor.onDefaultColor; 86 } 87 88 switch (logLevel) 89 { 90 case LogLevel.trace: 91 return s.black.onDefaultColor; 92 case LogLevel.info: 93 return s.defaultColor.onDefaultColor; 94 case LogLevel.warning: 95 return s.green.onDefaultColor; 96 case LogLevel.error: 97 return s.yellow.onDefaultColor; 98 case LogLevel.critical: 99 return s.black.onRed; 100 case LogLevel.fatal: 101 return s.yellow.onRed; 102 default: 103 assert(0); 104 } 105 } 106 }