1 /** 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * SPDX-License-Identifier: Apache-2.0. 4 */ 5 package software.amazon.awssdk.crt; 6 7 /** 8 * Static wrapper around native and crt logging. 9 * 10 * It is NOT safe to change the logging setup after it has been initialized. 11 */ 12 public class Log { 13 14 // Log must initialize the CRT in case it is the first API call made 15 static { CRT()16 new CRT(); 17 } 18 19 /* 20 * System properties for automatic logging initialization on CRT initialization 21 */ 22 private static final String LOG_DESTINATION_PROPERTY_NAME = "aws.crt.log.destination"; 23 private static final String LOG_FILE_NAME_PROPERTY_NAME = "aws.crt.log.filename"; 24 private static final String LOG_LEVEL_PROPERTY_NAME = "aws.crt.log.level"; 25 26 /** 27 * Enum that determines where logging should be routed to. 28 */ 29 private enum LogDestination { 30 None, 31 Stdout, 32 Stderr, 33 File 34 } 35 36 /** 37 * Enum that controls how detailed logging should be. 38 */ 39 public enum LogLevel { 40 None(0), 41 Fatal(1), 42 Error(2), 43 Warn(3), 44 Info(4), 45 Debug(5), 46 Trace(6); 47 48 private int level; 49 LogLevel(int value)50 LogLevel(int value) { 51 level = value; 52 } 53 getValue()54 public int getValue() { 55 return level; 56 } 57 }; 58 59 public enum LogSubject { 60 // aws-c-common 61 CommonGeneral(0x000), 62 CommonTaskScheduler(0x001), 63 64 // aws-c-io 65 IoGeneral(0x400), 66 IoEventLoop(0x401), 67 IoSocket(0x402), 68 IoSocketHandler(0x403), 69 IoTls(0x404), 70 IoAlpn(0x405), 71 IoDns(0x406), 72 IoPki(0x407), 73 IoChannel(0x408), 74 IoChannelBootstrap(0x409), 75 IoFileUtils(0x40A), 76 IoSharedLibrary(0x40B), 77 78 // aws-c-http 79 HttpGeneral(0x800), 80 HttpConnection(0x801), 81 HttpServer(0x802), 82 HttpStream(0x803), 83 HttpConnectionManager(0x804), 84 HttpWebsocket(0x805), 85 HttpWebsocketSetup(0x806), 86 87 // aws-c-mqtt 88 MqttGeneral(0x1400), 89 MqttClient(0x1401), 90 MqttTopicTree(0x1402), 91 92 // aws-c-auth 93 AuthGeneral(0x1800), 94 AuthProfile(0x1801), 95 AuthCredentialsProvider(0x1802), 96 AuthSigning(0x1803), 97 98 // aws-c-event-stream 99 EventStreamServerListener(0x1000), 100 // aws-c-s3 101 S3Client(0x4000), 102 103 // aws-crt-java, we're authoritative 104 JavaCrtGeneral(0x2400), 105 JavaCrtResource(0x2401), 106 JavaCrtS3(0x2402), 107 JavaAndroidKeychain(0x2403) 108 ; 109 LogSubject(int value)110 LogSubject(int value) { 111 this.value = value; 112 } 113 getValue()114 public int getValue() { return value; } 115 116 private int value; 117 }; 118 119 /** 120 * Logs a message at the specified log level. 121 * @param level (for filtering purposes) level attached to the log invocation 122 * @param subject (for filtering purposes) log subject 123 * @param message log string to write 124 */ log(LogLevel level, LogSubject subject, String message)125 public static void log(LogLevel level, LogSubject subject, String message) { 126 log(level.getValue(), subject.getValue(), message); 127 } 128 129 /** 130 * Examines logging-related system properties and initializes the logging system if they 131 * have been properly set. 132 */ initLoggingFromSystemProperties()133 public static void initLoggingFromSystemProperties() throws IllegalArgumentException { 134 String destinationString = System.getProperty(LOG_DESTINATION_PROPERTY_NAME); 135 String filenameString = System.getProperty(LOG_FILE_NAME_PROPERTY_NAME); 136 String levelString = System.getProperty(LOG_LEVEL_PROPERTY_NAME); 137 138 // If nothing was specified, disable logging 139 if (destinationString == null && levelString == null) { 140 return; 141 } 142 143 // If no destination wasn't specified, default to stderr 144 if (destinationString == null) { 145 destinationString = "Stderr"; 146 } 147 148 LogDestination destination = LogDestination.valueOf(destinationString); 149 LogLevel level = LogLevel.Warn; 150 if (levelString != null) { 151 level = LogLevel.valueOf(levelString); 152 } 153 154 switch(destination) { 155 case Stdout: 156 initLoggingToStdout(level.getValue()); 157 break; 158 159 case Stderr: 160 initLoggingToStderr(level.getValue()); 161 break; 162 163 case File: 164 if (filenameString == null) { 165 return; 166 } 167 168 initLoggingToFile(level.getValue(), filenameString); 169 break; 170 case None: 171 break; 172 } 173 } 174 175 /** 176 * Initializes logging to go to stdout 177 * @param level the filter level to apply to log calls 178 */ initLoggingToStdout(LogLevel level)179 public static void initLoggingToStdout(LogLevel level) { 180 initLoggingToStdout(level.getValue()); 181 } 182 183 /** 184 * Initializes logging to go to stderr 185 * @param level the filter level to apply to log calls 186 */ initLoggingToStderr(LogLevel level)187 public static void initLoggingToStderr(LogLevel level) { 188 initLoggingToStderr(level.getValue()); 189 } 190 191 /** 192 * Initializes logging to go to a file 193 * @param level the filter level to apply to log calls 194 * @param filename name of the file to direct logging to 195 */ initLoggingToFile(LogLevel level, String filename)196 public static void initLoggingToFile(LogLevel level, String filename) { 197 initLoggingToFile(level.getValue(), filename); 198 } 199 200 /******************************************************************************* 201 * native methods 202 ******************************************************************************/ log(int level, int subject, String logstring)203 private static native void log(int level, int subject, String logstring); 204 initLoggingToStdout(int level)205 private static native void initLoggingToStdout(int level); initLoggingToStderr(int level)206 private static native void initLoggingToStderr(int level); initLoggingToFile(int level, String filename)207 private static native void initLoggingToFile(int level, String filename); 208 }; 209