2
0

Log native mpw into Java.

This commit is contained in:
Maarten Billemont 2019-09-24 17:46:33 -04:00
parent fd1014926c
commit 1c6a5256c1
5 changed files with 142 additions and 48 deletions

View File

@ -714,7 +714,7 @@ void cli_mpw(Arguments *args, Operation *operation) {
if (!operation->site)
abort();
if (mpw_verbosity >= inf_level)
if (mpw_verbosity >= LogLevelInfo)
fprintf( stderr, "%s's %s for %s:\n[ %s ]: ",
operation->file->user->fullName, operation->purposeResult, operation->site->siteName, operation->identicon );

View File

@ -31,12 +31,12 @@ library {
toolChains {
withType( VisualCpp ) {
eachPlatform {
cppCompiler.withArguments { addAll( ['/TC', '/MT', '/Ox', '/DMPW_SODIUM=1', '/DSODIUM_STATIC', '/DSODIUM_EXPORT='] ) }
cppCompiler.withArguments { addAll( ['/TC', '/MT', '/Ox', '/DMPW_SODIUM=1', '/DSODIUM_STATIC', '/DSODIUM_EXPORT=', '/DMPW_LOG=mpw_log_app'] ) }
}
}
withType( GccCompatibleToolChain ) {
eachPlatform {
cppCompiler.withArguments { addAll( ['-x', 'c', '-O3', '-Werror', '-DMPW_SODIUM=1'] ) }
cppCompiler.withArguments { addAll( ['-x', 'c', '-O3', '-Werror', '-DMPW_SODIUM=1', '-DMPW_LOG=mpw_log_app'] ) }
}
}
}

View File

@ -7,11 +7,67 @@
// TODO: We may need to zero the jbytes safely.
static jobject logger;
static JNIEnv *env;
void mpw_log_app(LogLevel level, const char *format, ...) {
jmethodID method = NULL;
jclass class = (*env)->GetObjectClass( env, logger );
if (level >= LogLevelTrace)
method = (*env)->GetMethodID( env, class, "trace", "(Ljava/lang/String;)V" );
else if (level == LogLevelDebug)
method = (*env)->GetMethodID( env, class, "debug", "(Ljava/lang/String;)V" );
else if (level == LogLevelInfo)
method = (*env)->GetMethodID( env, class, "info", "(Ljava/lang/String;)V" );
else if (level == LogLevelWarning)
method = (*env)->GetMethodID( env, class, "warn", "(Ljava/lang/String;)V" );
else if (level <= LogLevelError)
method = (*env)->GetMethodID( env, class, "error", "(Ljava/lang/String;)V" );
va_list args;
va_start( args, format );
if (class && method && logger) {
char *message = NULL;
int length = vasprintf(&message, format, args);
if (length > 0)
(*env)->CallVoidMethod(env, logger, method, (*env)->NewStringUTF( env, message ));
if (message)
mpw_free(&message, (size_t) length);
}
else
// Can't log via slf4j, fall back to cli logger.
mpw_vlog_cli( level, format, args );
va_end( args );
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if ((*vm)->GetEnv( vm, (void **)&env, JNI_VERSION_1_6 ) != JNI_OK)
return -1;
jclass class = (*env)->FindClass( env, "org/slf4j/LoggerFactory" );
jmethodID method = (*env)->GetStaticMethodID( env, class, "getLogger", "(Ljava/lang/String;)Lorg/slf4j/Logger;" );
jstring name = (*env)->NewStringUTF( env, "com.lyndir.masterpassword.algorithm" );
if (class && method && name)
logger = (*env)->CallStaticObjectMethod( env, class, method, name );
else
wrn( "Couldn't initialize JNI logger." );
class = (*env)->GetObjectClass( env, logger );
if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isTraceEnabled", "()Z" ) ))
mpw_verbosity = LogLevelTrace;
else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isDebugEnabled", "()Z" ) ))
mpw_verbosity = LogLevelDebug;
else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isInfoEnabled", "()Z" ) ))
mpw_verbosity = LogLevelInfo;
else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isWarnEnabled", "()Z" ) ))
mpw_verbosity = LogLevelWarning;
else if ((*env)->CallBooleanMethod( env, logger, (*env)->GetMethodID( env, class, "isErrorEnabled", "()Z" ) ))
mpw_verbosity = LogLevelError;
else
mpw_verbosity = LogLevelFatal;
return JNI_VERSION_1_6;
}

View File

@ -34,9 +34,53 @@ MP_LIBS_BEGIN
#include "aes.h"
MP_LIBS_END
#ifdef inf_level
int mpw_verbosity = inf_level;
#endif
int mpw_verbosity = LogLevelInfo;
FILE *mpw_log_cli_file;
void mpw_log_cli(LogLevel level, const char *format, ...) {
va_list args;
va_start( args, format );
mpw_vlog_cli( level, format, args );
va_end( args );
}
void mpw_vlog_cli(LogLevel level, const char *format, va_list args) {
if (!mpw_log_cli_file)
mpw_log_cli_file = stderr;
if (mpw_verbosity >= level) {
if (mpw_verbosity >= LogLevelDebug) {
switch (level) {
case LogLevelTrace:
fprintf( mpw_log_cli_file, "[TRC] " );
break;
case LogLevelDebug:
fprintf( mpw_log_cli_file, "[DBG] " );
break;
case LogLevelInfo:
fprintf( mpw_log_cli_file, "[INF] " );
break;
case LogLevelWarning:
fprintf( mpw_log_cli_file, "[WRN] " );
break;
case LogLevelError:
fprintf( mpw_log_cli_file, "[ERR] " );
break;
case LogLevelFatal:
fprintf( mpw_log_cli_file, "[FTL] " );
break;
default:
fprintf( mpw_log_cli_file, "[???] " );
break;
}
}
vfprintf( mpw_log_cli_file, format, args );
fprintf( mpw_log_cli_file, "\n" );
}
if (level <= LogLevelFatal)
abort();
}
void mpw_uint16(const uint16_t number, uint8_t buf[2]) {

View File

@ -27,48 +27,42 @@ MP_LIBS_BEGIN
MP_LIBS_END
//// Logging.
typedef mpw_enum(int, LogLevel) {
/** Logging internal state. */
LogLevelTrace = 3,
/** Logging state and events interesting when investigating issues. */
LogLevelDebug = 2,
/** User messages. */
LogLevelInfo = 1,
/** Recoverable issues and user suggestions. */
LogLevelWarning = 0,
/** Unrecoverable issues. */
LogLevelError = -1,
/** Issues that lead to abortion. */
LogLevelFatal = -2,
};
LogLevel mpw_verbosity;
/** mpw_log_cli is a sink that writes log messages to the mpw_log_cli_file, which defaults to stderr. */
FILE *mpw_log_cli_file;
void mpw_log_cli(LogLevel level, const char *format, ...);
void mpw_vlog_cli(LogLevel level, const char *format, va_list args);
/** mpw_log_app is a sink placeholder that an application can implement to consume log messages. */
void mpw_log_app(LogLevel level, const char *format, ...);
/** The sink you want to channel the log messages into, defaults to mpw_log_cli. */
#ifndef MPW_LOG
#define MPW_LOG mpw_log_cli
#endif
#ifndef trc
extern int mpw_verbosity;
#ifndef mpw_log_do
#define mpw_log_do(level, format, ...) \
fprintf( stderr, format "\n", ##__VA_ARGS__ )
#endif
#ifndef mpw_log
#define mpw_log(level, format, ...) do { \
if (mpw_verbosity >= level) { \
mpw_log_do( level, format, ##__VA_ARGS__ ); \
} \
if (level <= -2) { \
abort(); \
} \
} while (0)
#endif
/** Logging internal state. */
#define trc_level 3
#define trc(format, ...) mpw_log( trc_level, format, ##__VA_ARGS__ )
/** Logging state and events interesting when investigating issues. */
#define dbg_level 2
#define dbg(format, ...) mpw_log( dbg_level, format, ##__VA_ARGS__ )
/** User messages. */
#define inf_level 1
#define inf(format, ...) mpw_log( inf_level, format, ##__VA_ARGS__ )
/** Recoverable issues and user suggestions. */
#define wrn_level 0
#define wrn(format, ...) mpw_log( wrn_level, format, ##__VA_ARGS__ )
/** Unrecoverable issues. */
#define err_level -1
#define err(format, ...) mpw_log( err_level, format, ##__VA_ARGS__ )
/** Issues that lead to abortion. */
#define ftl_level -2
#define ftl(format, ...) mpw_log( ftl_level, format, ##__VA_ARGS__ )
#define trc(format, ...) MPW_LOG( LogLevelTrace, format, ##__VA_ARGS__ )
#define dbg(format, ...) MPW_LOG( LogLevelDebug, format, ##__VA_ARGS__ )
#define inf(format, ...) MPW_LOG( LogLevelInfo, format, ##__VA_ARGS__ )
#define wrn(format, ...) MPW_LOG( LogLevelWarning, format, ##__VA_ARGS__ )
#define err(format, ...) MPW_LOG( LogLevelError, format, ##__VA_ARGS__ )
#define ftl(format, ...) MPW_LOG( LogLevelFatal, format, ##__VA_ARGS__ )
#endif
#ifndef min