Como hacer un log a un fichero con NSLog y el Apple System Logger

Autor: | Última modificación: 2 de noviembre de 2022 | Tiempo de Lectura: 2 minutos
Temas en este post:

Alternativas a NSLog: no hacen falta

NSLog es una función muy usada pero a menudo poco entendida. Es muy común, cuando alguien quiere hacer un log a un fichero, crearse dos macros: una que usa fprintf() y otra que no hace nada. Se decide cual usar mediante una constante de depuración, de tal forma que en la versión de release no se consumen recursos haciendo un log (NSLog tiene un coste sustancial).

#ifdef DEBUG     
#define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]); 
#else     
#define NSLog(...) {}               
#endif

Las tres cosas son una abominación sobre otra.

[NSAbominationStack: pushYetAnotherAbomination]

Vayamos por partes:

  1. No uses macros en C. No están bajo el control del compilador y terminarán creando bugs y haciendo ilegible el código.
  2. No uses una macro para llamar de forma condicional a NSLog. Aprende a usar las acciones de los puntos de interrupción: tu código estará más limpio y tendrá mejor rendimiento.
  3. No uses fprintf para escribir en un fichero. Primero porque hay opciones mejores con Cocoa y segundo porque es absolutamente innecesario.

El Apple System Logger

Desde OSX 10.4, contamos con Apple System Logger que se encarga de escribir a la base de datos de logs del sistema. Puedes buscar esa base de datos de la Console.app o desde tu propia app. Además, también puede escribir a uno o más ficheros de texto.

Creo que lo mejor es leer el artículo de Peter Hosey sobre el ASL para aprender a configurarlo y usarlo. Incluye una sección sobre como añadir ficheros al logger. Su API es de código abierto y para C, pero se pueden hacer «wrappers» en Objective C fácilmente.

También recomendaría ver el Google’s Toolbox for Mac, que entre otras cosas, tiene GTMLogger. Después de mucho trastear, terminé tirando a la basura mi implementación y tirando de GTMLogger.