variables/state, which is an improvement over other languages. Then
a place.". It's now, and here.
> The question is why should you go through extra hoops (however minor) to
> recognize a logging statement?
>
> There is a time and place for implicits, and this is not it - the use case
> here seems pretty weak and contrived. There is nothing wrong with typing
> logger.warn(...), it clearly documents that it's a logging statement, and
> such statements are simply not frequent enough to save much typing by
> omitting the "logger" part. I know that implicits are cool, but there is no
> need to abuse them for every little thing.
>
>
> On 18.06.2009 09:03, Ricky Clarkson wrote:
>>
>> Surely you can find where warn is defined by searching for an import
>> containing 'warn'. Or jump to declaration in your IDE.
>>
>> 2009/6/18 Blair Zajac <
blair@...>:
>>>
>>> On Jun 17, 2009, at 9:57 PM, Walter Smith wrote:
>>>
>>>> Hi!
>>>>
>>>> I think logging should be a part of the core libraries of a language...
>>>> it
>>>> is such an unbeloved matter that at least the logging api to use should
>>>> not
>>>> be something to discuss about in every project.
>>>>
>>>> There is one logging framework built into Java, but it is not very well
>>>> received. Especially in the Java enterprise world, log4j is used much
>>>> more
>>>> often for some good reasons, but you can't deploy multiple
>>>> configurations
>>>> for the same classes used in different enterprise applications within
>>>> one
>>>> JVM, if it's part of the parent class loader, i.e. it's used by the
>>>> container itself. And there is a third comprehensive logging framework
>>>> competing: logback. So it's a good idea for frameworks to be able to use
>>>> a
>>>> generic logging api, so that a customer can use *one* framework for all
>>>> the
>>>> frameworks in use. And generally Scala is right now in the role of such
>>>> a
>>>> framework, isn't it?
>>>>
>>>> I still see Apache commons logging being used a lot. I think this is not
>>>> much better than using prinln directly! It not only lacks important
>>>> features
>>>> like formatting messages only when needed, or MDCs; I understand that it
>>>> still causes perm gen memory leaks when hot deploying.
>>>>
>>>> There is a much better solution, though: SLF4J... IMHO every Java or
>>>> Scala
>>>> programmer should know it.
>>>>
>>>> But SLF4J is a Java api, so I tried to wrap it in "the Scala way":
>>>> 1. Logging is a trait that defines the logger using the name of the
>>>> class
>>>> you mix it into; a common and regularly used pattern now easily provided
>>>> by
>>>> a library... that's what I love Scala for.
>>>> 2. There is a sealed trait LogLevel with objects for error, info, etc.
>>>> that
>>>> you can pass around, e.g. into a library or to configure instances of a
>>>> class. To actually log at a LogLevel, you simply apply your parameters
>>>> to
>>>> it; the logger can be passed in as a implicit argument.
>>>> 3. The arguments that are used for your format are passed in by name, so
>>>> only get evaluated when the log level is enabled, i.e. it's ok to call
>>>> debug("client dns name {}", java.net.InetAddress.getByAddress(client));
>>>> the
>>>> lookup will only be made, if the debug log level is enabled... Scala
>>>> rules!
>>>>
>>>> BTW: Is there a simpler way to get an Array[Byte] literal than
>>>> Array(192.byteValue,168.byteValue,178.byteValue,1.byteValue)?
>>>
>>> The point of slf4j's format string, i.e. "The foobar's value is {}", is
>>> to
>>> avoid interpolation cost if the log message will not be used.
>>>
>>> The Scala way of dealing with this is to use by-name arguments. So you
>>> end
>>> up with
>>>
>>> trait Logger
>>> {
>>> def warn(msg : => String) : Unit
>>> }
>>>
>>> trait Slf4jLogger extends Logger
>>> {
>>> private val myRealLogger = Logger.getLogger(this.getClass.getName)
>>>
>>> private val isWarnEnabled = myRealLogger.isWarnEnabled
>>>
>>> def warn(msg : => String) : Unit
>>> {
>>> if (isWarnEnabled) {
>>> myRealLogger.warn(msg)
>>> }
>>> }
>>> }
>>>
>>> Then call it
>>>
>>> logger.warn("The foobar's value is " + foobar + ".")
>>>
>>> the string concatenation here won't be done unless
>>> my_real_logger.isWarnEnabled is true.
>>>
>>> BTW, I'm not a fan of implicits here. I'd much rather see a call
>>>
>>> logger.warn("It blew up!")
>>>
>>> than
>>>
>>> warn("It blew up!")
>>>
>>> It's clear I'm calling a logger and don't need to wonder where warn() is
>>> defined.
>>>
>>> Check out Lift's logger. It does this nicely and has a slf4j layer.
>>>
>>>
>>>
http://github.com/dpp/liftweb/blob/338119b8d7a76adcb9f45e9aa8a2b946d9c81118/lift-util/src/main/scala/net/liftweb/util/Log.scala>>>
>>>
http://github.com/dpp/liftweb/blob/338119b8d7a76adcb9f45e9aa8a2b946d9c81118/lift-util/src/main/scala/net/liftweb/util/Slf4jLog.scala>>>
>>> Regards,
>>> Blair
>>>
>>> --
>>> Blair Zajac, Ph.D.
>>> CTO, OrcaWare Technologies
>>> <
blair@...>
>>> Subversion training, consulting and support
>>>
http://www.orcaware.com/svn/>>>
>>>
>>>
>>
>>
>>
>
>