2010-07-26 11 views
9

He envuelto la API de la consola para proporcionar niveles de registro granulares, así como algunas otras características de azúcar.Cómo acceder a números de línea al envolver Firebug (o similar) Consola api

Esto funciona bien, el único problema es que Firebug (o cualquier otra consola) siempre informará el número de línea del que proviene el registro como la línea en la que se invoca la API de la consola.

¿Cómo sugeriría que haga que la consola registre el número de línea al que llamo mi función contenedora?

Preferiría una solución de navegador cruzada pero, en caso de que falle, un complemento de Firebug podría ser un buen comienzo.

FYI llamar a mi función loging así:

db.log(db.LogLevel.WARN, "Blah Blah Blah"); 
+0

Sería mejor si se puede explicar lo que se esperaba elaboradamente. ¿Desea obtener los números de línea de la invocación de su función? –

Respuesta

0

Así que esto acaba de entrar de nuevo, así que decidió volver a visitarlo

Ahora estoy más viejo y más sabio que es claro para mí una solución mucho mejor entonces lo que estaba tratando de hacer es llamar a las funciones de la consola como son, sino selectivamente reemplazarlos con funciones ficticias cuando el nivel está bajo. Esto me da un registro detallado y un número de línea preciso. Se han perdido algunas características de mi solución anterior, pero creo que este es un compromiso aceptable.

Aquí hay un recorte parcial de mi nuevo lib registro que muestra la solución principal

... 
levels : ["debug","info","warn","error"], 

    init : function(minLevel) { 
     var params = abm.getUrlParams(); 
     minLevel = params["debug"] || minLevel; 

     //TODO: firebug lite 
     window.console = window.console || {}; 

     var clear = false; 
     for (var i=0; i<self.levels.length; i++) { 
      var level = self.levels[i]; 
      originalFunctions[i] = originalFunctions[i] 
      || console[level] || fallback; 

      if (level && (clear || level===minLevel)) { 
       console[level] = originalFunctions[i]; 
       clear=true; 
      } else { 
       console[level] = suppressed(level); 
      } 
     } 

    } 
... 

Puede ver la cosa completa aquí: https://github.com/antiBaconMachine/abm-log

0

lo general mediante el debug() o error() en lugar de log() funciones hará que los números de línea que se mostrará. Creo que la consola de Google Chrome funciona de manera similar. (firebug reference)

+1

No se trata de mostrar números de línea, se trata de mostrar el número de línea DERECHO. Todas las funciones de registro muestran el número de línea en el que se llamó a la función de registro, en mi caso, como he envuelto esta función, siempre muestra el mismo número de línea. –

+0

Estás empezando a dejar los límites de las capacidades de javascript. ¿Puedo preguntarte qué estás buscando hacer? Solucionar problemas? ¿Depurar? –

3

Problema interesante ... Es posible que tenga un truco para ti. No puedo probar esto ahora, pero creo que podría funcionar.

Sabemos que una llamada a función normal no funcionará, así que comencé a pensar en #defines en C y en macros en varios otros idiomas. Desafortunadamente, javascript no tiene esto, pero quizás un truco eval funcionará. Estoy esperando que eval ejecute el código como si proviniera de la misma línea; si no, bleh, ignore el resto de esta respuesta.

Mi método funciona así:

  1. Cambiar la función db.Log para apuntar a eval (sí, ew)
  2. En lugar de pasar en sus LogLevels como argumento, crear funciones para cada una de ellas que devuelve una cadena con console.log y un mensaje personalizado.

Debe ser algo como esto:

db = {LogLevel: {}}; 
db.log = eval; 
db.LogLevel.warn = function(message) { 
    return "console.log('THIS IS A WARNING: " + message + "');"; 
}; 

Usted debe ser capaz de llamarlo así ahora:

db.log(db.LogLevel.warn("Blah blah blah")); 
+0

Idea interesante, gran pensamiento fuera de la caja y casi brillante. Se cae porque la mayoría de los navegadores no permiten alias eval como una característica de seguridad. En IE, funciona como se describe. Llamar a eval en su lugar podría ser una solución alternativa, aunque creo que esto empezaría a erosionar la utilidad de envolver la consola en primer lugar. Gran esfuerzo sin embargo. –

+1

@Ollie Edwards: ¡es mi culpa por no haberlo probado correctamente! Sin embargo, lo he comprobado hoy, en Firefox y Chrome, y aunque tienes razón en que hay restricciones de seguridad, parece que es solo si cambias el ** contexto ** de 'eval'. Por lo tanto, si no asigna 'log' al objeto' db' (simplemente créelo globalmente), puede alias 'eval' muy bien. –

1
//trust me, this way rocks! Auto prepend a logHead, yet keep correct line number displayed debug view. 
//Output sample: 
// 5/10 1:13:52.553 hi         a.js:100 
// 5/10 1:13:52.553 err         b.js:200 

    var Log = { 
     debug : true, 

     /* 
     * log.d(logData1, logData2, ...) 
     * --> console.log(getLogHead(), logData1, logData2, ...) 
     * 
     * @comment Using bind and property accesser 
     * @see http://ejohn.org/blog/javascript-getters-and-setters/ 
     */ 
     get d() { 
      if (!this.debug) return _emptyFunc; 
      return console.log.bind(console, this._getLogHeader()); 
     }, 

     /* 
     * output error info 
     */ 
     get e() { 
      return console.error.bind(console, this._getLogHeader()); 
     }, 

     /** 
     * get current time in 01/31 23:59:59.999 format 
     */ 
     _getLogHeader : function() { 

      var millisec = Date.now(); 
      this._dtNow.setTime(millisec); 
      //toLocaleString is 2013/01/31 23:59:59 
      return this._dtNow.toLocaleString().slice(5) + '.' + ('000' + millisec).slice(-3) + ' '; 
     }, 
     _dtNow: new Date(), 
     _emptyFunc: function() {} 
    }; 


    //enjoy it ! 
     Log.d('hi'); 
     Log.e('err'); 
+0

Parece interesante, tendré una obra de teatro –

0

Aquí hay dos maneras para envolver el registro sin perder contexto. El primero es un poco feo por parte de la persona que llama. El segundo solo se puede usar si no necesita los detalles de lo que se registró.

Véase el jsFiddle para una demostración: http://jsfiddle.net/epQ95/1/

// logger method 1: allows for fully functional log-wrapping without losing context, 
//     but, it is very ugly from the caller's perspective. 
var debug = function() { 
    // do my extra special stuff 
    window.console.log("logging to server 1: ", arguments); 

    // do regular console logging, if possible 
    if (window.console && window.console.log) { 
     return window.console.log.apply.bind(window.console.log, window.console, arguments); 
    } else { 
     return function() {}; 
    } 
}; 

// caller 
debug("logger method", 1)(); 

// logger method 2: pretty calling, but you don't know what was logged, 
//     just that something definitely was. 
var Logger = {}; 
Logger.__defineGetter__("debug", function() { 
    // do my extra special stuff 
    window.console.log("logging to server 2: don't know what was logged"); 

    // do regular console logging, if possible 
    if (window.console && window.console.log) { 
     return console.log.bind(window.console); 
    } else { 
     return function() {}; 
    } 
}); 

// caller 
Logger.debug("logger method", 2); 
Cuestiones relacionadas