Skip to content

Commit

Permalink
Started reworking debug
Browse files Browse the repository at this point in the history
Finally got around to improve debugging a little:

- log priority has been renamed to log level
- the debug settings (DEBUG preprocessor flag and MAX_LOG_LEVEL in CWDebug) are passed to the web library
- the web library passes the debug information to a remote once it has connected, so all devices use the same settings
- the web library doesn't rely on the native layer to filter by level anymore, but rather does it itself. This prevents unnecessary log messages on native-less remotes
- CWDebug.err is now forwareded to ErrLog() in Objective-C, this way we make sure errors are always logged regardless of settings
  • Loading branch information
Mario Schreiner committed Feb 12, 2015
1 parent 7ab8452 commit 884385a
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 178 deletions.
24 changes: 12 additions & 12 deletions Connichiwa/BLWebSocketsServer/libwebsockets/libwebsockets.c
Expand Up @@ -2268,18 +2268,18 @@ void lwsl_emit_syslog(int level, const char *line)

void _lws_log(int filter, const char *format, ...)
{
char buf[256];
va_list ap;

if (!(log_level & filter))
return;

va_start(ap, format);
vsnprintf(buf, (sizeof buf), format, ap);
buf[(sizeof buf) - 1] = '\0';
va_end(ap);

lwsl_emit(filter, buf);
// char buf[256];
// va_list ap;
//
// if (!(log_level & filter))
// return;
//
// va_start(ap, format);
// vsnprintf(buf, (sizeof buf), format, ap);
// buf[(sizeof buf) - 1] = '\0';
// va_end(ap);
//
// lwsl_emit(filter, buf);
}

/**
Expand Down
22 changes: 18 additions & 4 deletions Connichiwa/CWDebug.h
Expand Up @@ -10,14 +10,14 @@



void cwLogNew(int priority, NSString *source, NSString *file, int line, NSString *format, ...);
void _cwLogNew(int priority, NSString *source, NSString *file, int line, NSString *format, ...);

//_CWLog() is a low-level macro that will only log if the CWDEBUG compiler flag is set to 1
//Thanks http://stackoverflow.com/questions/969130/how-to-print-out-the-method-name-and-line-number-and-conditionally-disable-nslog
#ifdef CWDEBUG
# define _CWLog(prio, source, file, line, format, ...) cwLogNew(prio, source, file, line, format, ##__VA_ARGS__)
#ifdef DEBUG
# define _CWLog(prio, source, file, line, format, ...) _cwLogNew(prio, source, file, line, format, ##__VA_ARGS__)
#else
# define _CWLog(...)
# define _CWLog(...) //we don't need this but it saves us a method call
#endif

//CWLog is a higher-level logging macro to be used by the native layer
Expand All @@ -26,6 +26,18 @@ void cwLogNew(int priority, NSString *source, NSString *file, int line, NSString
//BTLog is a higher-level logging macro to be used by BT-related functions in the native layer
#define BTLog(prio, format, ...) _CWLog(prio, @"BLUETOOTH", @((strrchr(__FILE__, '/') ? : __FILE__ - 1) + 1), __LINE__, format, ##__VA_ARGS__)

//HTTPLog is a higher-level logging macro to be used by HTTP Server-related functions in the native layer
#define HTTPLog(prio, format, ...) _CWLog(prio, @"HTTP", @((strrchr(__FILE__, '/') ? : __FILE__ - 1) + 1), __LINE__, format, ##__VA_ARGS__)

//WSLog is a higher-level logging macro to be used by Websocket-related functions in the native layer
#define WSLog(prio, format, ...) _CWLog(prio, @"WEBSOCKET", @((strrchr(__FILE__, '/') ? : __FILE__ - 1) + 1), __LINE__, format, ##__VA_ARGS__)

//MCLog is a higher-level logging macro to be used by Multipeer Connectivity-related functions in the native layer
#define MCLog(prio, format, ...) _CWLog(prio, @"MULTIPEER", @((strrchr(__FILE__, '/') ? : __FILE__ - 1) + 1), __LINE__, format, ##__VA_ARGS__)

//WLLog is a higher-level logging macro to be used by messages sent from the JavaScript WebLibrary
#define WLLog(prio, format, ...) _CWLog(prio, @"WEBLIB",@"?????", -1, format, ##__VA_ARGS__)

//ErrLog is a higher-level logging macro to be used to log errors
#define ErrLog(format, ...) _CWLog(1, @"ERROR", @((strrchr(__FILE__, '/') ? : __FILE__ - 1) + 1), __LINE__, format, ##__VA_ARGS__)

Expand All @@ -48,4 +60,6 @@ void cwLogNew(int priority, NSString *source, NSString *file, int line, NSString
*/
+ (void)executeInDebug:(void (^)(void))block;

+ (int)logLevel;

@end
17 changes: 10 additions & 7 deletions Connichiwa/CWDebug.m
Expand Up @@ -8,7 +8,7 @@

#import "CWDebug.h"

int const MAX_LOG_PRIORITY = 4;
int const MAX_LOG_LEVEL = 4;



Expand All @@ -17,7 +17,7 @@ @implementation CWDebug

+ (BOOL)isDebugging
{
#ifdef CWDEBUG
#ifdef DEBUG
return YES;
#else
return NO;
Expand All @@ -27,11 +27,15 @@ + (BOOL)isDebugging

+ (void)executeInDebug:(void (^)(void))block
{
#ifdef CWDEBUG
#ifdef DEBUG
block();
#endif
}

+ (int)logLevel {
return MAX_LOG_LEVEL;
}


static long longestSourceLength = 10;

Expand All @@ -40,7 +44,7 @@ + (void)executeInDebug:(void (^)(void))block
* Custom logging function tailored towards usage in Connichiwa. It will log a message if the given priority is smaller or equal to MAX_LOG_PRIORITY and the given source is set up as an active debug source.
* Thanks to http://stackoverflow.com/questions/1354728/in-xcode-is-there-a-way-to-disable-the-timestamps-that-appear-in-the-debugger-c
*
* @param priority The logging priority determines the "level" of logging a message belongs to. A higher priority means the message is likely to occur more often. This allows us to reduce log messages by decreasing MAX_LOG_PRIORITY. The log priorities are roughly defined as follows:
* @param level A higher level means the message is likely to occur more often. This allows us to reduce log messages by decreasing MAX_LOG_LEVEL. The levels are roughly defined as follows:
* 1 -- very rudimentary application flow (bt advertising starts, webserver was launched, ...)
* 2 -- more detailed application flow (remote did connect/disconnect, getting intial data, ...)
* 3 -- log message on most method calls, giving a detailed overview of the application flow
Expand All @@ -52,12 +56,12 @@ + (void)executeInDebug:(void (^)(void))block
* @param format The format of the message. A format string like it is also used in NSLog()
* @param ... The arguments for the format string
*/
void cwLogNew(int priority, NSString *source, NSString *file, int line, NSString *format, ...)
void _cwLogNew(int level, NSString *source, NSString *file, int line, NSString *format, ...)
{
NSArray *activeDebugSources = nil; //TODO is defined every time, lame, but static NSArray is not possible

source = [source uppercaseString];
if (priority <= MAX_LOG_PRIORITY && ([source isEqualToString:@"ERROR"] || activeDebugSources == nil || [activeDebugSources containsObject:source]))
if ([CWDebug isDebugging] && level <= MAX_LOG_LEVEL && ([source isEqualToString:@"ERROR"] || activeDebugSources == nil || [activeDebugSources containsObject:source]))
{
static dispatch_once_t token;
static NSDateFormatter *dateFormatter;
Expand All @@ -82,7 +86,6 @@ void cwLogNew(int priority, NSString *source, NSString *file, int line, NSString
source = [source stringByAppendingString:spaces];
}

// NSString *finalString = [NSString stringWithFormat:@"%@ %@ %@:%d -- %@\n", source, dateString, file, line, formattedString];
NSString *finalString = [NSString stringWithFormat:@"%@ %@ -- %@\n", source, dateString, formattedString];
[[NSFileHandle fileHandleWithStandardOutput] writeData:[finalString dataUsingEncoding:NSUTF8StringEncoding]];
}
Expand Down
6 changes: 4 additions & 2 deletions Connichiwa/CWUtil.m
Expand Up @@ -16,7 +16,7 @@
/**
* The options used when creating JSON strings. In debug mode, we use a pretty representation, otherwise a shorter, less readable presentation
*/
#ifdef CWDEBUG
#ifdef DEBUG
NSJSONWritingOptions const JSON_WRITING_OPTIONS = NSJSONWritingPrettyPrinted;
#else
NSJSONWritingOptions const JSON_WRITING_OPTIONS = kNilOptions;
Expand Down Expand Up @@ -78,7 +78,7 @@ + (NSArray *)deviceInterfaceAddresses
{
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
int success = -1;

NSMutableArray *ips = [NSMutableArray arrayWithCapacity:1];

Expand Down Expand Up @@ -117,6 +117,8 @@ + (NSArray *)deviceInterfaceAddresses

temp_addr = temp_addr->ifa_next;
}
} else {
ErrLog(@"Error getting IPs: %@ (%d)", [NSString stringWithUTF8String:strerror(errno)], errno);
}

// Free memory
Expand Down
24 changes: 14 additions & 10 deletions Connichiwa/CWWebLibraryManager.m
Expand Up @@ -71,7 +71,7 @@ - (void)_sendToView_disconnectWebsocket;
/**
* Tells the web library if we are running in debug mode or not
*/
- (void)_sendToView_cwdebug;
- (void)_sendToView_debuginfo;

/**
* Tells the web library the unique connichiwa identifier we are known under
Expand Down Expand Up @@ -295,11 +295,12 @@ - (void)_sendToView_disconnectWebsocket
}


- (void)_sendToView_cwdebug
- (void)_sendToView_debuginfo
{
NSDictionary *data = @{
@"_name": @"cwdebug",
@"cwdebug": @([CWDebug isDebugging])
@"_name": @"debuginfo",
@"debug": @([CWDebug isDebugging]),
@"logLevel": @([CWDebug logLevel])
};
[self _sendToView_dictionary:data];
}
Expand Down Expand Up @@ -395,10 +396,8 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView
{
CWLog(3, @"Web library webview did load, setting things up and connecting websocket");



[self _registerJSCallbacks];
[self _sendToView_cwdebug];
[self _sendToView_debuginfo];
[self _sendToView_connectWebsocket];
}
else if (self.state == CWWebLibraryManagerStateDisconnecting)
Expand All @@ -422,7 +421,7 @@ - (void)createWebViewContext {
//Register JS error handler
self.webViewContext.exceptionHandler = ^(JSContext *c, JSValue *e) {
dispatch_async(dispatch_get_main_queue(), ^{
_CWLog(1, @"WEBLIB", @"?????", -1, @"JAVASCRIPT ERROR: %@. Stack: %@", e, [e valueForProperty:@"stack"]);
ErrLog(@"JAVASCRIPT ERROR: %@. Stack: %@", e, [e valueForProperty:@"stack"]);
});
};

Expand All @@ -432,11 +431,16 @@ - (void)createWebViewContext {
NSArray *components = [logMessage componentsSeparatedByString:@"|"]; //array should contain: prio, message
if ([components count] != 2)
{
_CWLog(1, @"WEBLIB", @"?????", -1, logMessage);
WLLog(1, logMessage);
}
else
{
_CWLog([[components objectAtIndex:0] intValue], @"WEBLIB", @"?????", -1, [components objectAtIndex:1]);
//First component should be a priority or can be "ERROR" for logging an error
if ([[components objectAtIndex:0] isEqualToString:@"ERROR"]) {
ErrLog([components objectAtIndex:1]);
} else {
WLLog([[components objectAtIndex:0] intValue], [components objectAtIndex:1]);
}
}
};
self.webViewContext[@"console"][@"log"] = logger;
Expand Down
24 changes: 12 additions & 12 deletions Connichiwa/GCDWebServer/Core/GCDWebServer.m
Expand Up @@ -87,18 +87,18 @@
#ifdef __GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__

void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* format, ...) {
static const char* levelNames[] = {"DEBUG", "VERBOSE", "INFO", "WARNING", "ERROR", "EXCEPTION"};
static int enableLogging = -1;
if (enableLogging < 0) {
enableLogging = (isatty(STDERR_FILENO) ? 1 : 0);
}
if (enableLogging) {
va_list arguments;
va_start(arguments, format);
NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
va_end(arguments);
fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]);
}
// static const char* levelNames[] = {"DEBUG", "VERBOSE", "INFO", "WARNING", "ERROR", "EXCEPTION"};
// static int enableLogging = -1;
// if (enableLogging < 0) {
// enableLogging = (isatty(STDERR_FILENO) ? 1 : 0);
// }
// if (enableLogging) {
// va_list arguments;
// va_start(arguments, format);
// NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
// va_end(arguments);
// fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]);
// }
}

#endif
Expand Down
81 changes: 39 additions & 42 deletions ConnichiwaResources/weblib/connichiwa.js
Expand Up @@ -204,6 +204,7 @@ var OOP = (function() {
extendSingleton : extendSingleton
};
})();
/* global OOP */
"use strict";


Expand All @@ -213,48 +214,43 @@ var OOP = (function() {
*
* @namespace CWDebug
*/
var CWDebug = (function()
{
/**
* true if debug mode is on, otherwise false
*/
var debug = true;
var CWDebug = OOP.createSingleton("Connichiwa", "CWDebug", {
_debug: false,
_logLevel: 0,

var enableDebug = function() {
debug = true;
};
"public setDebug": function(v) {
this._debug = v;
},

"public setLogLevel": function(v) {
this._logLevel = v;
},

var disableDebug = function() {
debug = false;
};

/**
* Logs a message to the console if debug mode is on
*
* @param {int} priority The priority of the message. Messages with lower priority are printed at lower debug states.
* @param {string} message the message to log
*
* @memberof CWDebug
*/
var log = function(priority, message)
{
// if (priority > 3) return;
if (debug) console.log(priority + "|" + message);
};
"public setDebugInfo": function(info) {
console.log("SETTING DEBUG INFO: "+info.debug+" || "+info.logLevel);
if (info.debug) CWDebug.setDebug(info.debug);
if (info.logLevel) CWDebug.setLogLevel(info.logLevel);
},

var err = function(priority, message) {
if (debug) console.err(priority + "|" + message);
};

return {
enableDebug : enableDebug,
disableDebug : disableDebug,
log : log,
err : err
};
})();
/* global Connichiwa, CWSystemInfo, CWUtil, CWEventManager, CWDebug */
"public getDebugInfo": function() {
return { debug: this._debug, logLevel: this._logLevel };
},


"public log": function(level, msg) {
if (this._debug && level <= this._logLevel) {
console.log(level + "|" + msg);
}
},

"public err": function(msg) {
if (this._debug) {
console.log("ERROR" + "|" + msg);
}
}
});/* global Connichiwa, CWSystemInfo, CWUtil, CWEventManager, CWDebug */
/* global nativeCallConnectRemote */
"use strict";

Expand Down Expand Up @@ -1919,7 +1915,7 @@ var CWNativeMasterCommunication = OOP.createSingleton("Connichiwa", "CWNativeMas
var object = JSON.parse(message);
switch (object._name)
{
case "cwdebug": this._parseDebug(object); break;
case "debuginfo": this._parseDebugInfo(object); break;
case "connectwebsocket": this._parseConnectWebsocket(object); break;
case "localinfo": this._parseLocalInfo(object); break;
case "devicedetected": this._parseDeviceDetected(object); break;
Expand All @@ -1932,10 +1928,9 @@ var CWNativeMasterCommunication = OOP.createSingleton("Connichiwa", "CWNativeMas
},


_parseDebug: function(message)
_parseDebugInfo: function(message)
{
if (message.cwdebug === true) CWDebug.enableDebug();
else CWDebug.disableDebug();
CWDebug.setDebugInfo(message);
},


Expand Down Expand Up @@ -2452,11 +2447,14 @@ OOP.extendSingleton("Connichiwa", "CWWebsocketMessageParser",

device.connectionState = CWDeviceConnectionState.CONNECTED;
nativeCallRemoteDidConnect(device.getIdentifier());

//Make sure the remote uses the same logging settings as we do
device.send("_debuginfo", CWDebug.getDebugInfo());

// AutoLoad files from Connichiwa.autoLoad on the new remote device
var didConnectCallback = function() {
CWEventManager.trigger("deviceConnected", device);
};

var loadOtherFile = function(device, file) {
//As of now, "other" files are only CSS
var extension = file.split(".").pop().toLowerCase();
Expand Down Expand Up @@ -2619,7 +2617,6 @@ OOP.extendSingleton("Connichiwa", "Connichiwa", {

_onWebsocketClose: function()
{
console.log("close");
CWDebug.log(3, "Websocket closed");
this._cleanupWebsocket();

Expand Down

0 comments on commit 884385a

Please sign in to comment.