8

Having the following code: log.info("parameters {} and {}", param1, param2) compiles and works well with SLF4J in Scala

However if I want to pass more arguments, I need to use Array:

log.info("parameters {} and {} and {}", Array(param1, param2,param3)) 

which simply substitutes first parameter with array.toString and leaves rest of parameters unbound.

The following code

log.info("parameters {} and {} and {}", Array(param1, param2,param3) : _*) 

doesn't compile, because of:

error: overloaded method value info with alternatives:
(org.slf4j.Marker,java.lang.String)Unit <and>
(java.lang.String,java.lang.Throwable)Unit <and>
(java.lang.String,Array[java.lang.Object])Unit <and>
(java.lang.String,Any)Unit
cannot be applied to (java.lang.String, Any)
log.info("parameters {} and {} and {}", Array(param1, param2,param3) : _*) 

What am I missing here?

jdevelop
  • 12,176
  • 10
  • 56
  • 112

5 Answers5

6

I guess it all depends on the inferred type. The log.info method that takes an array is expecting an Array[AnyRef]. So as an alternative to the cast you could do

log.info("parameters {} and {} and {}", Array[AnyRef](1, 2, "a"): _*)

But this won't work as there's a restriction on implicit conversions between Int -> AnyRef. For those, you'll need a type ascription:

log.info("parameters {} and {} and {}", 
   Array[AnyRef](1: Integer, 2: Integer, "a"): _*)

See this question for more details: Result type of an implicit conversion must be more specific than AnyRef

Community
  • 1
  • 1
Bruno Bieth
  • 2,317
  • 20
  • 31
2

You should use a scala wrapper for slf4j like grizzled

If you're not bound to slf4j, you should check out Logula. I've been playing with that recently and I like it.

Falmarri
  • 47,727
  • 41
  • 151
  • 191
  • 3
    Every project dependency is an extra future maintenance work. For example, "Logula" mentioned by @Falmarri in 2012 is now marked as "abandoned" – Alexander Azarov Feb 11 '16 at 09:39
0

what if you use string interpolation? like so:

log.info(f"parameters ${param1} and ${param2} and ${param3}")
  • 1
    log.info(s"parameters ${ 1/ 0 } and..") will throw / by zero exception even if in WARN log level – Bùi Việt Thành Oct 08 '13 at 07:01
  • true you can make it lazy val though. lazy val dividedByZero = f"${1/0}"; val levelWarn = true; if (levelWarn) println(dividedByZero); this will throw NpE only when levelWarn is true. I added semicolon to delimit lines since I cannot add CR – Luis Ramirez-Monterosa Oct 15 '13 at 13:28
-1

Try this:

Array(...).asInstanceOf[Array[Object]]
kiritsuku
  • 52,967
  • 18
  • 114
  • 136
S-C
  • 1,909
  • 1
  • 16
  • 14
  • I did try this. It doesn't give an error, but it doesn't do the right thing either. It will put the entire array as a string on the first argument "{}" and leave the remaining blank ... – marios Aug 02 '15 at 05:53
-1

Here is how I do it.

LOGGER.info("encode: {}, code: {}, length: {}", Array(messageWrapper, methodCode, bytes.length).asInstanceOf[Array[AnyRef]])

Cheers

Patrick
  • 87
  • 1
  • 4