• C-Octothorpe (unregistered) in reply to hoodaticus
    hoodaticus:
    Also, did anyone else find this to be ugly and a CodeSmell?
    public class AuthenticationService {
        static Log log = LogFactory.getLogger(AuthenticationService.class);
    //...
    }
    They're having to switch on the class in the getLogger method. Eww. How about trying some fucking polymorphism? I know it's a new fad, having been invented only 60 years ago, but sometimes, fads are a good thing.

    Probably not (at least I would hope not). More than likely they're just using it for logging: AuthenticationService log: [log message body]. This just creates a static instance of the logger for this specific class just once per app-domain (at least it's this way in .net), and I doubt they're switching on the type in the method call.

  • C-Octothorpe (unregistered) in reply to wthyrbendragon
    wthyrbendragon:
    Studley:
    It's all very well testing that the logger is logging, but it needs some additional logging to check that the logger logging is logging.

    Reading this caused me to spontaneously create a log. Thanks. I'll be back after a quick change.

    Really? I dropped one when I read this:

    Matt Westwood:
    I heard about the constipated mathematician who worked out logs with a pencil but this is several orders of magnitude funnier.
  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    hoodaticus:
    Also, did anyone else find this to be ugly and a CodeSmell?
    public class AuthenticationService {
        static Log log = LogFactory.getLogger(AuthenticationService.class);
    //...
    }
    They're having to switch on the class in the getLogger method. Eww. How about trying some fucking polymorphism? I know it's a new fad, having been invented only 60 years ago, but sometimes, fads are a good thing.

    Probably not (at least I would hope not). More than likely they're just using it for logging: AuthenticationService log: [log message body]. This just creates a static instance of the logger for this specific class just once per app-domain (at least it's this way in .net), and I doubt they're switching on the type in the method call.

    They're passing the class to the getLogger method. A class that has no interfaces and does not inherit. Either they have a useless parameter in there, or they are switching on type.

    If they had no parameter there, I would agree with you. And you made me think, so thanks.

  • (cs) in reply to Anonymous
    Anonymous:
    Attempted to post a sensible comment but it's devolved into an Akismet bash. Everything I try to submit is blocked - even when there are no URLs or links in the message. Quoting other messages seems to trigger it as well, even with no URLs in the quote. I literally cannot post ANYTHING today and the only reason I expect this to work is cruel, cruel irony.

    That response was logged to the file /irony/DailyWTF.log

  • Anonymous Coward (unregistered) in reply to Anonymous
    For starters, you can get rid of that abysmal home-made captcha and replace it with something that doesn't have the answer encoded in the querystring.
    [image] [image] [image] [image]
  • ffff (unregistered)
  • C-Octothorpe (unregistered) in reply to hoodaticus
    hoodaticus:
    C-Octothorpe:
    hoodaticus:
    Also, did anyone else find this to be ugly and a CodeSmell?
    public class AuthenticationService {
        static Log log = LogFactory.getLogger(AuthenticationService.class);
    //...
    }
    They're having to switch on the class in the getLogger method. Eww. How about trying some fucking polymorphism? I know it's a new fad, having been invented only 60 years ago, but sometimes, fads are a good thing.

    Probably not (at least I would hope not). More than likely they're just using it for logging: AuthenticationService log: [log message body]. This just creates a static instance of the logger for this specific class just once per app-domain (at least it's this way in .net), and I doubt they're switching on the type in the method call.

    They're passing the class to the getLogger method. A class that has no interfaces and does not inherit. Either they have a useless parameter in there, or they are switching on type.

    If they had no parameter there, I would agree with you. And you made me think, so thanks.

    Sorry, I just shot in the dark considering I don't know Java at all. Does this pass in an instance of the class or is it like typeof(AuthenticationService) in .Net?

  • Anonymous Coward (unregistered) in reply to hoodaticus
    hoodaticus:
    If they had no parameter there, I would agree with you. And you made me think, so thanks.

    Actually, the method is using Class.getName() to get a logger category string out of the class passed. You can instead pass the fully qualified class name (or anything else, really) as a string, but passing the class has less chance of typos.

  • Design Pattern (unregistered) in reply to hoodaticus
    hoodaticus:
    Also, did anyone else find this to be ugly and a CodeSmell?
    public class AuthenticationService {
        static Log log = LogFactory.getLogger(AuthenticationService.class);
    //...
    }
    They're having to switch on the class in the getLogger method.
    Not really. From Logger:
      static public Logger getLogger(Class clazz) {
        return LogManager.getLogger(clazz.getName());
      } 
    
    From LogManager:
     public
      static Logger getLogger(final Class clazz) {
        // Delegate the actual manufacturing of the logger to the logger repository.
        return getLoggerRepository().getLogger(clazz.getName());
      } 
    

    From the default LoggerRepository called Hierarchy:

      Hashtable ht; 
    ...
      public Logger getLogger(String name) {
        return getLogger(name, defaultFactory);
      } 
    
      public Logger getLogger(String name, LoggerFactory factory) 
      {
        //System.out.println("getInstance("+name+") called.");
        CategoryKey key = new CategoryKey(name);
        // Synchronize to prevent write conflicts. Read conflicts (in
        // getChainedLevel method) are possible only if variable
        // assignments are non-atomic.
        Logger logger;
    	
        synchronized(ht) {
          Object o = ht.get(key);
          if(o == null) {
            logger = factory.makeNewLoggerInstance(name);
            logger.setHierarchy(this);
            ht.put(key, logger);
            updateParents(logger);
            return logger;
          }
    ...
    

    So not a switch, a Hashtable lookup on the Class-name.

    hoodaticus:
    How about trying some fucking polymorphism? I know it's a new fad, having been invented only 60 years ago, but sometimes, fads are a good thing.

    Polymorphism works wonderful for Object instances, but this is a static variable populated by static Java code - Java is not completely object-oriented.

  • Alex (unregistered)

    If a logger logs the logging but nobody is there to read the logs does it actually logs anything ?

  • Lifestyle Choices (unregistered) in reply to kastein
    kastein:
    I think this site has gone from critiquing and showcasing horrible code to exemplifying it. Between the terrible captcha, retarded meme/troll spam, idiots trying to make lame jokes about the captchas, akismet, and the lack of articles recently...
    What do you darnn expect? Even the HAL 9000 went homicidal crazy when it didn't have enough to do on a long space voyage. When you don't post an article in days and then crap out a lame one like this, you're going to have some unfortunate souls trying to make meaning out of nothingness.
  • EatenByAGrue (unregistered)

    "... the reason these guys had no peer review was that they had no peers."

    If TDWTF has taught me nothing else, it's that these guys have millions of peers. The dunce cap would be a useful accessory for many of them.

  • C-Octothorpe (unregistered) in reply to Design Pattern
    Design Pattern:
    hoodaticus:
    Also, did anyone else find this to be ugly and a CodeSmell?
    public class AuthenticationService {
        static Log log = LogFactory.getLogger(AuthenticationService.class);
    //...
    }
    They're having to switch on the class in the getLogger method.
    Not really. From Logger:
      static public Logger getLogger(Class clazz) {
        return LogManager.getLogger(clazz.getName());
      } 
    
    From LogManager:
     public
      static Logger getLogger(final Class clazz) {
        // Delegate the actual manufacturing of the logger to the logger repository.
        return getLoggerRepository().getLogger(clazz.getName());
      } 
    

    From the default LoggerRepository called Hierarchy:

      Hashtable ht; 
    ...
      public Logger getLogger(String name) {
        return getLogger(name, defaultFactory);
      } 
    
      public Logger getLogger(String name, LoggerFactory factory) 
      {
        //System.out.println("getInstance("+name+") called.");
        CategoryKey key = new CategoryKey(name);
        // Synchronize to prevent write conflicts. Read conflicts (in
        // getChainedLevel method) are possible only if variable
        // assignments are non-atomic.
        Logger logger;
    	
        synchronized(ht) {
          Object o = ht.get(key);
          if(o == null) {
            logger = factory.makeNewLoggerInstance(name);
            logger.setHierarchy(this);
            ht.put(key, logger);
            updateParents(logger);
            return logger;
          }
    ...
    

    So not a switch, a Hashtable lookup on the Class-name.

    hoodaticus:
    How about trying some fucking polymorphism? I know it's a new fad, having been invented only 60 years ago, but sometimes, fads are a good thing.

    Polymorphism works wonderful for Object instances, but this is a static variable populated by static Java code - Java is not completely object-oriented.

    Why does the code perform the lock first before checking the HT for the key? Shouldn't it check the HT first, if null lock, check again (race condition), then add if still null?

  • Pytry (unregistered) in reply to Smiddy

    You may have your logging. Just don't wiz on the electric firewalls...

  • Wonko (unregistered)

    So 1 server handles the requests, the other 6 servers hold the log file....

  • (cs) in reply to Bert Glanstron
    Bert Glanstron:
    Dear NAGESH,

    In case you can't tell, this is a grown-up place. The fact that you insist on using your ridiculous handle clearly shows that you're too young and too stupid to be using the interNET.

    Go away and grow up.

    Sincerely, Bert Glanstron

    Wow! A personal note. Are you boog?

  • (cs) in reply to Design Pattern
    Design Pattern:
    hoodaticus:
    Also, did anyone else find this to be ugly and a CodeSmell?
    public class AuthenticationService {
        static Log log = LogFactory.getLogger(AuthenticationService.class);
    //...
    }
    They're having to switch on the class in the getLogger method.
    Not really. From Logger:
      static public Logger getLogger(Class clazz) {
        return LogManager.getLogger(clazz.getName());
      } 
    
    From LogManager:
     public
      static Logger getLogger(final Class clazz) {
        // Delegate the actual manufacturing of the logger to the logger repository.
        return getLoggerRepository().getLogger(clazz.getName());
      } 
    

    From the default LoggerRepository called Hierarchy:

      Hashtable ht; 
    ...
      public Logger getLogger(String name) {
        return getLogger(name, defaultFactory);
      } 
    
      public Logger getLogger(String name, LoggerFactory factory) 
      {
        //System.out.println("getInstance("+name+") called.");
        CategoryKey key = new CategoryKey(name);
        // Synchronize to prevent write conflicts. Read conflicts (in
        // getChainedLevel method) are possible only if variable
        // assignments are non-atomic.
        Logger logger;
    	
        synchronized(ht) {
          Object o = ht.get(key);
          if(o == null) {
            logger = factory.makeNewLoggerInstance(name);
            logger.setHierarchy(this);
            ht.put(key, logger);
            updateParents(logger);
            return logger;
          }
    ...
    

    So not a switch, a Hashtable lookup on the Class-name.

    hoodaticus:
    How about trying some fucking polymorphism? I know it's a new fad, having been invented only 60 years ago, but sometimes, fads are a good thing.

    Polymorphism works wonderful for Object instances, but this is a static variable populated by static Java code - Java is not completely object-oriented.

    Thanks for the explanation, dude. I was actually expecting type-specific event hookups and all other sorts of crap in getLogger, and I was confused as to why they didn't do this with an ILoggable interface instance as the parameter to GetLogger. I didn't think about it reflecting on type until later.
  • (cs) in reply to Nagesh
    Nagesh:
    Bert Glanstron:
    Dear NAGESH,

    In case you can't tell, blah blah blah...

    Sincerely, Bert Glanstron

    [b][color=lame]Wow![/color][/b] A personal note. Are you boog?
    Absolutely not; when I have something to say, I say it directly.

    (By the way, you really need to brush up on your TDWTF memes there Nagesh.)

  • Bake and Code (unregistered)

    Actually, this is perfectly valid, since embedded systems without a file system can not have a log file. The only available output would be the console! I would make use of XML however since that greatly speeds up processing on embedded systems, especially low performance chips.

  • (cs)

    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

  • C-Octothorpe (unregistered) in reply to Captain Oblivious
    Captain Oblivious:
    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

    I think the fact that the runtime even MADE it to that line of code implies that it succeeded... or something.

  • Some Jerk (unregistered)

    system.out.println( "Ow! My fingers hurt." ); system.out.println( "And I am thirsty too." ); system.out.println( "I am going to go get a cup of coffee." ); system.out.println( "I am back now. I guess I better do my job." ); system.out.println( "Getting paid per line of code isn't all that bad." );

  • (cs) in reply to boog
    boog:
    Nagesh:
    Bert Glanstron:
    Dear NAGESH,

    In case you can't tell, blah blah blah...

    Sincerely, Bert Glanstron

    [b][color=lame]Wow![/color][/b] A personal note. Are you boog?
    Absolutely not; when I have something to say, I say it directly.

    (By the way, you really need to brush up on your TDWTF memes there Nagesh.)

    Before my time, booger!!!

  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    Captain Oblivious:
    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

    I think the fact that the runtime even MADE it to that line of code implies that it succeeded... or something.

    Yeah, but don't you feel at least a little dirty inside when you print success without any testing? I know I do.

  • C-Octothorpe (unregistered) in reply to Some Jerk
    Some Jerk:
    system.out.println( "Starting to print: Ow! My fingers hurt." ); system.out.println( "Ow! My fingers hurt." ); system.out.println( "Success printing: Ow! My fingers hurt." );

    system.out.println( "Starting to print: And I am thirsty too." ); system.out.println( "And I am thirsty too." ); system.out.println( "Success printing: And I am thirsty too." );

    system.out.println( "Starting to print: I am going to go get a cup of coffee." ); system.out.println( "I am going to go get a cup of coffee." ); system.out.println( "Success printing: I am going to go get a cup of coffee." );

    system.out.println( "Starting to print: I am back now. I guess I better do my job." ); system.out.println( "I am back now. I guess I better do my job." ); system.out.println( "Success printing: I am back now. I guess I better do my job." );

    system.out.println( "Starting to print: Getting paid per line of code isn't all that bad." ); system.out.println( "Getting paid per line of code isn't all that bad." ); system.out.println( "Success printing: Getting paid per line of code isn't all that bad." );

    FTFY

  • C-Octothorpe (unregistered) in reply to hoodaticus
    hoodaticus:
    C-Octothorpe:
    Captain Oblivious:
    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

    I think the fact that the runtime even MADE it to that line of code implies that it succeeded... or something.

    Yeah, but don't you feel at least a little dirty inside when you print success without any testing? I know I do.

    No, I usually do stuff with farm animals when I want to feel dirty...

    That's right, you heard me!

  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    hoodaticus:
    C-Octothorpe:
    Captain Oblivious:
    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

    I think the fact that the runtime even MADE it to that line of code implies that it succeeded... or something.

    Yeah, but don't you feel at least a little dirty inside when you print success without any testing? I know I do.

    No, I usually do stuff with farm animals when I want to feel dirty...

    That's right, you heard me!

    Is bloddy disgusting.

  • C-Octothorpe (unregistered) in reply to Nagesh
    Nagesh:
    C-Octothorpe:
    hoodaticus:
    C-Octothorpe:
    Captain Oblivious:
    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

    I think the fact that the runtime even MADE it to that line of code implies that it succeeded... or something.

    Yeah, but don't you feel at least a little dirty inside when you print success without any testing? I know I do.

    No, I usually do stuff with farm animals when I want to feel dirty...

    That's right, you heard me!

    Is bloddy disgusting.

    OH please, don't act all high and mighty... I saw you eyeing the goat at the market this morning. That's right, you thought I didn't see you, but I did.

  • techpaul (unregistered) in reply to Yaos
    Yaos:
    But who logs the logger that logs the logger? It is such a slippery slope for so much logging to be in the hands of so few loggers.

    Never was so much logged by so many to so few logs.

    FILE_NOT_FOUND DISK_FULL SERVER_FULL

    Just like the day many years ago in a distant workplace...(part 3 now renamed part 6)

    In the morning staff come in, cannot log onto network.

    Check main server, server busy or should we say the main disk drive very, very busy, disk activity lights mimicing a speeded up disco light. Console shows partial error message from backup process.

    Reboot server and check drives, string of new bad blocks in the system log. So an error occured at the end of backup which was

    Error in backup process
    logged to main system log
     bad block in main system log
      logged to main system log
       bad block in main system log
        logged to main system log
          bad block in main system log
           logged to main system log
            bad block in main system log
             logged to main system log
              ......

    Bad blocks all the way down.

    At least at the end of backup volume the backup process did not rewind the tape and start the next volume on the same tape!

  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    Captain Oblivious:
    TRWTF is logging success without testing anything between the "Processing..." and "success" parts.

    I think the fact that the runtime even MADE it to that line of code implies that it succeeded... or something.

    So why bother with the "Processing..." part, when that is already logged by the "Getting Token" part?

    The logs don't log what they say they are logging.

  • (cs) in reply to Nagesh
    Nagesh:
    boog:
    ...you really need to brush up on your TDWTF memes there Nagesh.
    Before my time, booger!!!
    Now you know why I provided a link. </duh>
  • Design Pattern (unregistered) in reply to C-Octothorpe
    C-Octothorpe:
    Why does the code perform the lock first before checking the HT for the key? Shouldn't it check the HT first, if null lock, check again (race condition), then add if still null?
    Well, if you know the magic words you can ask Google for an answer. The magic words are "Double-checked Locking is broken".
  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    Some Jerk:
    system.out.println( "Starting to print: Ow! My fingers hurt." ); system.out.println( "Ow! My fingers hurt." ); system.out.println( "Success printing: Ow! My fingers hurt." );

    system.out.println( "Starting to print: And I am thirsty too." ); system.out.println( "And I am thirsty too." ); system.out.println( "Success printing: And I am thirsty too." );

    system.out.println( "Starting to print: I am going to go get a cup of coffee." ); system.out.println( "I am going to go get a cup of coffee." ); system.out.println( "Success printing: I am going to go get a cup of coffee." );

    system.out.println( "Starting to print: I am back now. I guess I better do my job." ); system.out.println( "I am back now. I guess I better do my job." ); system.out.println( "Success printing: I am back now. I guess I better do my job." );

    system.out.println( "Starting to print: Getting paid per line of code isn't all that bad." ); system.out.println( "Getting paid per line of code isn't all that bad." ); system.out.println( "Success printing: Getting paid per line of code isn't all that bad." );

    FTFY

    #!/bin/bash

    echo "system.out.println ( "Invoking code generator." );" >> today.java echo "system.out.println ( "Generating code:" );" >> today.java echo "system.out.println ( "Success.");" >> today.java

    $0

  • Flavin (unregistered)

    So much logging, not liking.

  • Decius (unregistered) in reply to hoodaticus
    hoodaticus:
    Decius:
    Why use the unnatural and artificial log(Logging) functions when you can use the natural ln(Logging) function?
    Calculus jokes are below puns on the hierarchy of humor.

    Good thing that logarithms, including the natural logarithm, developed separately from calculus; they describe the critical principle of the slide rule, among other things. Calculus serves mainly to describe the area or volume of a bounded region, or the line or plane tangent to a line or surface.

    Further, a calculus joke which is also a pun clearly falls into the intersection of the two. As such, they cannot be 'below' puns.

    By the way, you got epic trolled by a math geek.

  • (cs) in reply to boog
    boog:
    Nagesh:
    boog:
    ...you really need to brush up on your TDWTF memes there Nagesh.
    Before my time, booger!!!
    Now you know why I provided a link. </duh>

    Thanks.

  • (cs)

    This is totally unacceptable: They should be logging the stack trace, too!

  • Ã (unregistered) in reply to Nagesh
    Nagesh:
    boog:
    Nagesh:
    boog:
    ...you really need to brush up on your TDWTF memes there Nagesh.
    Before my time, booger!!!
    Now you know why I provided a link. </duh>

    Thanks.

    Are you guys married?

  • (cs) in reply to Ã
    Ã:
    Nagesh:
    boog:
    Nagesh:
    boog:
    ...you really need to brush up on your TDWTF memes there Nagesh.
    Before my time, booger!!!
    Now you know why I provided a link. </duh>

    Thanks.

    Are you guys married?
    Nope, he's all yours.

  • anon (unregistered) in reply to Alex
    Alex:
    If a logger logs the logging but nobody is there to read the logs does it actually logs anything ?

    The philosophical statement will go out the window after the server crashes due to the disk being full.

    CAPTCHA: nulla On second thought your statment might be valid if logging to dev\null.

  • stu (unregistered) in reply to anon
    anon:
    ÃÆâ€â„Â:
    Nagesh:
    anon:
    frist

    if akismet will let me post...

    Sorry anon, yuo're late to party./
    Idiots...
    What kind of idiot name is "ÃÆâ€â„Â" ?
    Just imagine his password.

  • Niels Rasmussen (unregistered) in reply to hoodaticus
    hoodaticus:
    Decius:
    Why use the unnatural and artificial log(Logging) functions when you can use the natural ln(Logging) function?
    Calculus jokes are below puns on the hierarchy of humor.

    But verse is still worse!

  • (cs) in reply to Decius
    Decius:
    hoodaticus:
    Decius:
    Why use the unnatural and artificial log(Logging) functions when you can use the natural ln(Logging) function?
    Calculus jokes are below puns on the hierarchy of humor.

    Good thing that logarithms, including the natural logarithm, developed separately from calculus; they describe the critical principle of the slide rule, among other things. Calculus serves mainly to describe the area or volume of a bounded region, or the line or plane tangent to a line or surface.

    Further, a calculus joke which is also a pun clearly falls into the intersection of the two. As such, they cannot be 'below' puns.

    By the way, you got epic trolled by a math geek.

    Thanks, I already knew what Calculus is. And almost every use of the natural log I have ever seen was one of the following:

    1. A calculus expression
    2. An algebraic simplification of a calculus expression for use by statisticians, financial planners, and other morons.

    As to instances of number 2, I almost always convert them back into the original calculus and evaluate the definite integral or derivative or whatever it is that gets the answer.

    It's prettier that way.

    P.S. - I served you back. Now... it's on.

  • (cs) in reply to stu
    stu:
    anon:
    ÃÆâ€â„Â:
    Nagesh:
    anon:
    frist

    if akismet will let me post...

    Sorry anon, yuo're late to party./
    Idiots...
    What kind of idiot name is "ÃÆâ€â„Â" ?
    Just imagine his password.

    He has not registered for very same reason. He's trying to be extra super smart by putting all these unicode character data in his user name.

  • anon (unregistered) in reply to Nagesh
    Nagesh:
    stu:
    anon:
    ÃÆâ€â„Â:
    Nagesh:
    anon:
    frist

    if akismet will let me post...

    Sorry anon, yuo're late to party./
    Idiots...
    What kind of idiot name is "ÃÆâ€â„Â" ?
    Just imagine his password.

    He has not registered for very same reason. He's trying to be extra super smart by putting all these unicode character data in his user name.

    I can't believe you morons don't understand that username. Obviously you've never heard of a little thing called the "internet".

  • Curiousity Piqued (unregistered) in reply to anon
    anon:
    Nagesh:
    stu:
    anon:
    ÃÆâ€â„Â:
    Nagesh:
    anon:
    frist

    if akismet will let me post...

    Sorry anon, yuo're late to party./
    Idiots...
    What kind of idiot name is "ÃÆâ€â„Â" ?
    Just imagine his password.

    He has not registered for very same reason. He's trying to be extra super smart by putting all these unicode character data in his user name.

    I can't believe you morons don't understand that username. Obviously you've never heard of a little thing called the "internet".

    Web search doesn't provide any illumination. Can you please explain, or at least post a link?

  • anon (unregistered) in reply to Curiousity Piqued
    Curiousity Piqued:
    anon:
    Nagesh:
    stu:
    anon:
    ÃÆâ€â„Â:
    Nagesh:
    anon:
    frist

    if akismet will let me post...

    Sorry anon, yuo're late to party./
    Idiots...
    What kind of idiot name is "ÃÆâ€â„Â" ?
    Just imagine his password.

    He has not registered for very same reason. He's trying to be extra super smart by putting all these unicode character data in his user name.

    I can't believe you morons don't understand that username. Obviously you've never heard of a little thing called the "internet".

    Web search doesn't provide any illumination. Can you please explain, or at least post a link?

    Well, I guess I can give you a clue. A web search is all you need, but bear in mind that some of those characters are not actually searchable characters. You know how Google automatically ignores certain symbols in search terms? Exactly. Figure out which bits are searchable and you'll be on your way.

Leave a comment on “Logging the Logger”

Log In or post as a guest

Replying to comment #:

« Return to Article