2012-04-16 1 views
2

настоящее время я использую следующий DebugLog макросДинамически включения NSLogs

#if defined(DEBUG) && defined(useDebugLogs) 
#define DebugLog(s, ...) NSLog(@"<%s:(%d)> %@", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]) 
#else 
#define DebugLog(s, ...) 
#endif 

Однако теперь с испытательного полета, позволяя удаленного журналирования это немного устарели.

В основном, что я хочу сделать, это добавить переключатель в свой settings.plist, чтобы позволить пользователю включать удаленное ведение журнала.

Я сталкивалась с этим учебник http://jomnius.blogspot.com/2011/09/how-to-do-dynamic-debug-logging-in.html

Однако, это очень плохое объяснение и на самом деле не похоже на работу.

+0

Вы когда-нибудь пробовали [NSLogger] (https://github.com/fpillet/NSLogger)? –

+0

DEBUG определяется только во время ... (сюрприза) отладки. В коде выпуска это не сработает. – CodaFi

+0

@ AndyFriese Я не использовал его, однако, я видел его в комментариях к этому учебнику, но он кажется почти слишком большим. Я просто хочу простой переключатель – endy

ответ

3

хорошо, лучший способ ИМО просто всегда отправлять журналы и настройки вашей реализации, так что вы видите именно то, что вы хотите. вы либо хотите аналитику, либо не будете использовать их. есть ошибка, или нет. прокладывайте себе путь и улучшайте соотношение сигнал/шум. anyways ...

Вы могли бы просто создать специальную функцию для этой цели. он может условно регистрироваться или не основываться на некоторой переменной в вашей реализации. обратите внимание, что вы можете направить свой va_list по телефону NSLogv, а не NSLog, или вы можете использовать -[NSString initWithFormat:arguments:] направить сообщение + аргументы в другом месте:

MONDebugLog.h

extern void MONDebugLog(NSString * format, ...) NS_FORMAT_FUNCTION(1,2); 

MONDebugLog.m

void MONDebugLog(NSString * format, ...) { 

    enum { 
     MONLog_Undefined, 
     MONLog_Enable, 
     MONLog_Disable 
    }; 

    static int DoLog = MONLog_Undefined; 
    if (MONLog_Undefined == DoLog) { 
     DoLog = ...load from plist or defaults and set to Log_Enable or Log_Disable...; 
    } 

    if (MONLog_Disable == DoLog) { 
     return; 
    } 
    va_list arguments; 
    va_start(arguments, format); 
    NSString * str = [[NSString alloc] initWithFormat:format arguments:arguments]; 
    va_end(arguments); 
    ...now log or xmit str... 
} 
1

Вы можете попробовать что-то вроде этого:

#define boolDebug_IsActivated  [[NSUserDefaults standardUserDefaults] boolForKey:@"UseDebug"] 

#define DebugLog(s, ...) \ 
if (boolDebug_IsActivated) {\ 
    NSLog(@"<%s:(%d)> %@", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__]);\ 
} \ 
else {\ 
} 

Если вы хотите, чтобы включить/выключить, просто изменить значение объекта «UseDebug» в NSUserDefaults.

Пример:

[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"UseDebug"]; 
DebugLog(@"comment that should not appear"); 
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"UseDebug"]; 
DebugLog(@"comment that should appear"); 
+0

представляется самым простым решением. Но будет ли он каждый раз проверять UserDefaults? Похоже, это будет довольно медленно. – endy

2

Если вы хотите просто включить или выключить ведение журнала, вам будет легко, но . Идея перенаправить поток ошибок в/Dev/нуль:

#include <fcntl.h> 
#include <unistd.h> 

void setLoggingEnabled(BOOL enabled) 
{ 
    static int copyOfStdErr = -1; 
    if (enabled) { 
     if (copyOfStdErr == -1) 
      return; 
     dup2(copyOfStdErr, STDERR_FILENO); 
     close(copyOfStdErr); 
     copyOfStdErr = -1; 
    } else { 
     if (copyOfStdErr != -1) 
      return; 
     copyOfStdErr = dup(STDERR_FILENO); 
     int fd = open("/dev/null", O_WRONLY); 
     dup2(fd, STDERR_FILENO); 
     close(fd); 
    } 
} 

Это решение имеет ряд преимуществ:

  • Вы не должны использовать свой собственный механизм протоколирования в коде, он просто работает с NSLog
  • В игре нет магии препроцессора.
  • Он также работает для сторонних библиотек, которые выдают выходные данные.