Merge pull request #187 from cconlon/jsonDebugLog

Add option to print debug logs in JSON format
master
JacobBarthelmeh 2024-09-20 15:59:38 -06:00 committed by GitHub
commit 370ada7b7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 161 additions and 18 deletions

View File

@ -219,6 +219,7 @@ and what each enables.
| --- | --- | --- | --- |
| wolfssl.debug | "false" | "true" | Enables native wolfSSL debug logging |
| wolfjsse.debug | "false" | "true | Enables wolfJSSE debug logging |
| wolfjsse.debugFormat | | "JSON" | Switches debug output format |
| wolfsslengine.debug | "false" | "true" | Enables SSLEngine debug logging |
| wolfsslengine.io.debug | "false" | "true" | Enables SSLEngine I/O bytes log |
@ -240,6 +241,35 @@ System.setProperty("wolfsslengine.debug", "true);
JDK debug logging can be enabled using the `-Djavax.net.debug=all` option.
### JSON Log Message Format
Debug messages can be output in JSON format for consumption by tools such as
DataDog. Setting the following System property to "JSON" will cause all debug
messages to print in JSON instead of the default text output:
```
System.setProperty("wolfjsse.debugFormat", "JSON");
```
This can also be specified at runtime on the command line like so:
```
-Dwolfjsse.debug=true -Dwolfjsse.debugFormat=JSON
```
Debug messages will look similar to the following when output in JSON format:
```
{
"@timestamp": "2024-04-05 11:13:07.193",
"level": "INFO",
"logger_name": "wolfJSSE",
"message": "[ WolfSSLTrustManager] entered engineInit()",
"thread_name": "main",:
"thread_id": "1"
}
```
## Building for Android
wolfSSL JNI and JSSE can be built and used on the Android platform, either

View File

@ -37,10 +37,19 @@ import com.wolfssl.WolfSSLLoggingCallback;
public class WolfSSLDebug {
/**
* boolean to check if debug mode is on
* Check if debug mode is on.
*
* Is true if "wolfjsse.debug" is set to "true", otherwise false.
*/
public static final boolean DEBUG = checkProperty();
/**
* Check if JSON debug mode is on.
*
* Is true if "wolfjsse.debugFormat" is set to "JSON", otherwise false.
*/
public static final boolean DEBUG_JSON = jsonOutEnabled();
/**
* Error level debug message
*/
@ -58,6 +67,11 @@ public class WolfSSLDebug {
*/
private static WolfSSLNativeLoggingCallback nativeLogCb = null;
/**
* Check if "wolfjsse.debug" System property is set to "true".
*
* @return true if set to "true", otherwise return false
*/
private static boolean checkProperty() {
String enabled = System.getProperty("wolfjsse.debug");
@ -69,6 +83,22 @@ public class WolfSSLDebug {
return false;
}
/**
* Check if "wolfjsse.debugFormat" is set to "JSON".
*
* @return true if set to "JSON", otherwise false.
*/
private static boolean jsonOutEnabled() {
String enabled = System.getProperty("wolfjsse.debugFormat");
if ((enabled != null) && (enabled.equalsIgnoreCase("JSON"))) {
return true;
}
return false;
}
/**
* Prints out a message to the console
* @param string message to be printed
@ -77,9 +107,62 @@ public class WolfSSLDebug {
System.out.println("wolfJSSE: " + string);
}
/**
* Internal method to print debug message as JSON for consumption by
* tools such as DataDog.
*/
private static synchronized void logJSON(String tag, String msg,
long threadID, String threadName, String className) {
System.out.printf(
"{\n" +
" \"@timestamp\": \"%s\",\n" +
" \"level\": \"%s\",\n" +
" \"logger_name\": \"wolfJSSE\",\n" +
" \"message\": \"%s\",\n" +
" \"thread_name\": \"%s\",:\n" +
" \"thread_id\": \"%s\"\n" +
"}\n",
new Timestamp(new java.util.Date().getTime()),
tag, "[" + className + "] " + msg,
threadID, threadName
);
}
/**
* Internal method to print debug message with byte array hex as JSON,
* for consumption by tools such as DataDog.
*/
private static synchronized void logJSONHex(String tag, String label,
long threadID, String threadName, String className, byte[] in, int sz) {
/* Convert byte[] to hex string */
StringBuilder builder = new StringBuilder();
for (byte b: in) {
builder.append(String.format("%02X", b));
}
logJSON(tag, label + " [" + sz + "]: " + builder.toString(), threadID,
threadName, className);
}
/**
* Checks if debugging is turned on and prints out the message.
*
* Output format can be controlled with the "wolfjsse.debugFormat"
* System property. If not set, default debug output format will be used.
* If set to "JSON", all debug logs will be output in the following JSON
* format, which can be read by DataDog:
*
* {
* "@timestamp": "2024-04-05 11:13:07.193",
* "level": "INFO",
* "logger_name": "wolfJSSE",
* "message": "debug message",
* "thread_name": "thread_name",:
* "thread_id": "thread_ID"
* }
*
* @param cl class being called from to get debug info
* @param tag level of debug message i.e. WolfSSLDebug.INFO
* @param string message to be printed out
@ -88,16 +171,40 @@ public class WolfSSLDebug {
String string) {
if (DEBUG) {
System.out.println(new Timestamp(new java.util.Date().getTime()) +
" [wolfJSSE " + tag + ": TID " +
Thread.currentThread().getId() + ": " +
cl.getSimpleName() + "] " + string);
long threadID = Thread.currentThread().getId();
String threadName = Thread.currentThread().getName();
String className = cl.getSimpleName();
if (DEBUG_JSON) {
logJSON(tag, string, threadID, threadName, className);
}
else {
System.out.println(
new Timestamp(new java.util.Date().getTime()) +
" [wolfJSSE " + tag + ": TID " + threadID + ": " +
className + "] " + string);
}
}
}
/**
* Print out a byte array in hex if debugging is enabled.
*
* Output format can be controlled with the "wolfjsse.debugFormat"
* System property. If not set, default debug output format will be used.
* If set to "JSON", all debug logs will be output in the following JSON
* format, which can be read by DataDog:
*
* {
* "@timestamp": "2024-04-05 11:13:07.193",
* "level": "INFO",
* "logger_name": "wolfJSSE",
* "message": "label [sz]: array hex string",
* "thread_name": "thread_name",:
* "thread_id": "thread_ID"
* }
*
* @param cl class this method is being called from
* @param tag level of debug message i.e. WolfSSLDebug.INFO
* @param label label string to print with hex
@ -110,26 +217,32 @@ public class WolfSSLDebug {
if (DEBUG) {
int i = 0, j = 0;
int printSz = 0;
long tid = Thread.currentThread().getId();
String clName = null;
long threadID = Thread.currentThread().getId();
String threadName = Thread.currentThread().getName();
String className = null;
if (cl == null || in == null || sz == 0) {
return;
}
clName = cl.getSimpleName();
className = cl.getSimpleName();
printSz = Math.min(in.length, sz);
System.out.print("[wolfJSSE " + tag + ": TID " + tid + ": " +
clName + "] " + label + " [" + sz + "]: ");
for (i = 0; i < printSz; i++) {
if ((i % 16) == 0) {
System.out.printf("\n[wolfJSSE " + tag + ": TID " +
tid + ": " + clName + "] %06X", j * 8);
j++;
}
System.out.printf(" %02X ", in[i]);
if (DEBUG_JSON) {
logJSONHex(tag, label, threadID, threadName, className, in, sz);
}
else {
System.out.print("[wolfJSSE " + tag + ": TID " + threadID +
": " + className + "] " + label + " [" + sz + "]: ");
for (i = 0; i < printSz; i++) {
if ((i % 16) == 0) {
System.out.printf("\n[wolfJSSE " + tag + ": TID " +
threadID + ": " + className + "] %06X", j * 8);
j++;
}
System.out.printf(" %02X ", in[i]);
}
System.out.println("");
}
System.out.println("");
}
}