| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache license, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the license for the specific language governing permissions and |
| * limitations under the license. |
| */ |
| package org.apache.logging.log4j.scala |
| |
| import org.apache.logging.log4j.message.{EntryMessage, Message} |
| import org.apache.logging.log4j.spi.{AbstractLogger, ExtendedLogger} |
| import org.apache.logging.log4j.{Level, Marker} |
| |
| import scala.quoted.* |
| |
| /** |
| * Inspired from [[https://github.com/typesafehub/scalalogging ScalaLogging]]. |
| */ |
| private object LoggerMacro { |
| // Trace |
| |
| def traceMsg(underlying: Expr[Logger], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE)) $underlying.trace($message) } |
| } |
| |
| def traceMsgThrowable(underlying: Expr[Logger], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE)) $underlying.trace($message, $throwable) } |
| } |
| |
| def traceMarkerMsg(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE, $marker)) $underlying.trace($marker, $message) } |
| } |
| |
| def traceMarkerMsgThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE, $marker)) $underlying.trace($marker, $message, $throwable) } |
| } |
| |
| def traceCseq(underlying: Expr[Logger], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, '{Level.TRACE}, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def traceCseqThrowable(underlying: Expr[Logger], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, '{Level.TRACE}, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def traceMarkerCseq(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, '{Level.TRACE}, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def traceMarkerCseqThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, '{Level.TRACE}, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def traceObject(underlying: Expr[Logger], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE)) $underlying.trace($message) } |
| } |
| |
| def traceObjectThrowable(underlying: Expr[Logger], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE)) $underlying.trace($message, $throwable) } |
| } |
| |
| def traceMarkerObject(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE, $marker)) $underlying.trace($marker, $message) } |
| } |
| |
| def traceMarkerObjectThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.TRACE, $marker)) $underlying.trace($marker, $message, $throwable) } |
| } |
| |
| // Debug |
| |
| def debugMsg(underlying: Expr[Logger], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG)) $underlying.debug($message) } |
| } |
| |
| def debugMsgThrowable(underlying: Expr[Logger], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG)) $underlying.debug($message, $throwable) } |
| } |
| |
| def debugMarkerMsg(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG, $marker)) $underlying.debug($marker, $message) } |
| } |
| |
| def debugMarkerMsgThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG, $marker)) $underlying.debug($marker, $message, $throwable) } |
| } |
| |
| def debugCseq(underlying: Expr[Logger], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, '{Level.DEBUG}, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def debugCseqThrowable(underlying: Expr[Logger], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, '{Level.DEBUG}, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def debugMarkerCseq(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, '{Level.DEBUG}, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def debugMarkerCseqThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, '{Level.DEBUG}, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def debugObject(underlying: Expr[Logger], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG)) $underlying.debug($message) } |
| } |
| |
| def debugObjectThrowable(underlying: Expr[Logger], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG)) $underlying.debug($message, $throwable) } |
| } |
| |
| def debugMarkerObject(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG, $marker)) $underlying.debug($marker, $message) } |
| } |
| |
| def debugMarkerObjectThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.DEBUG, $marker)) $underlying.debug($marker, $message, $throwable) } |
| } |
| |
| // Info |
| |
| def infoMsg(underlying: Expr[Logger], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO)) $underlying.info($message) } |
| } |
| |
| def infoMsgThrowable(underlying: Expr[Logger], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO)) $underlying.info($message, $throwable) } |
| } |
| |
| def infoMarkerMsg(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO, $marker)) $underlying.info($marker, $message) } |
| } |
| |
| def infoMarkerMsgThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO, $marker)) $underlying.info($marker, $message, $throwable) } |
| } |
| |
| def infoCseq(underlying: Expr[Logger], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, '{Level.INFO}, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def infoCseqThrowable(underlying: Expr[Logger], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, '{Level.INFO}, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def infoMarkerCseq(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, '{Level.INFO}, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def infoMarkerCseqThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, '{Level.INFO}, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| |
| def infoObject(underlying: Expr[Logger], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO)) $underlying.info($message) } |
| } |
| |
| def infoObjectThrowable(underlying: Expr[Logger], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO)) $underlying.info($message, $throwable) } |
| } |
| |
| def infoMarkerObject(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO, $marker)) $underlying.info($marker, $message) } |
| } |
| |
| def infoMarkerObjectThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.INFO, $marker)) $underlying.info($marker, $message, $throwable) } |
| } |
| |
| //Warn |
| |
| def warnMsg(underlying: Expr[Logger], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN)) $underlying.warn($message) } |
| } |
| |
| def warnMsgThrowable(underlying: Expr[Logger], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN)) $underlying.warn($message, $throwable) } |
| } |
| |
| def warnMarkerMsg(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN, $marker)) $underlying.warn($marker, $message) } |
| } |
| |
| def warnMarkerMsgThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN, $marker)) $underlying.warn($marker, $message, $throwable) } |
| } |
| |
| def warnCseq(underlying: Expr[Logger], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, '{Level.WARN}, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def warnCseqThrowable(underlying: Expr[Logger], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, '{Level.WARN}, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def warnMarkerCseq(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, '{Level.WARN}, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def warnMarkerCseqThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, '{Level.WARN}, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def warnObject(underlying: Expr[Logger], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN)) $underlying.warn($message) } |
| } |
| |
| def warnObjectThrowable(underlying: Expr[Logger], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN)) $underlying.warn($message, $throwable) } |
| } |
| |
| def warnMarkerObject(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN, $marker)) $underlying.warn($marker, $message) } |
| } |
| |
| def warnMarkerObjectThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.WARN, $marker)) $underlying.warn($marker, $message, $throwable) } |
| } |
| |
| //Error |
| |
| def errorMsg(underlying: Expr[Logger], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR)) $underlying.error($message) } |
| } |
| |
| def errorMsgThrowable(underlying: Expr[Logger], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR)) $underlying.error($message, $throwable) } |
| } |
| |
| def errorMarkerMsg(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR, $marker)) $underlying.error($marker, $message) } |
| } |
| |
| def errorMarkerMsgThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR, $marker)) $underlying.error($marker, $message, $throwable) } |
| } |
| |
| def errorCseq(underlying: Expr[Logger], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, '{Level.ERROR}, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def errorCseqThrowable(underlying: Expr[Logger], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, '{Level.ERROR}, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def errorMarkerCseq(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, '{Level.ERROR}, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def errorMarkerCseqThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, '{Level.ERROR}, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def errorObject(underlying: Expr[Logger], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR)) $underlying.error($message) } |
| } |
| |
| def errorObjectThrowable(underlying: Expr[Logger], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR)) $underlying.error($message, $throwable) } |
| } |
| |
| def errorMarkerObject(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR, $marker)) $underlying.error($marker, $message) } |
| } |
| |
| def errorMarkerObjectThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.ERROR, $marker)) $underlying.error($marker, $message, $throwable) } |
| } |
| |
| //Fatal |
| |
| def fatalMsg(underlying: Expr[Logger], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL)) $underlying.fatal($message) } |
| } |
| |
| def fatalMsgThrowable(underlying: Expr[Logger], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL)) $underlying.fatal($message, $throwable) } |
| } |
| |
| def fatalMarkerMsg(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL, $marker)) $underlying.fatal($marker, $message) } |
| } |
| |
| def fatalMarkerMsgThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[Message], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL, $marker)) $underlying.fatal($marker, $message, $throwable) } |
| } |
| |
| def fatalCseq(underlying: Expr[Logger], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, '{Level.FATAL}, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def fatalCseqThrowable(underlying: Expr[Logger], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, '{Level.FATAL}, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def fatalMarkerCseq(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, '{Level.FATAL}, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def fatalMarkerCseqThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, '{Level.FATAL}, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def fatalObject(underlying: Expr[Logger], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL)) $underlying.fatal($message) } |
| } |
| |
| def fatalObjectThrowable(underlying: Expr[Logger], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL)) $underlying.fatal($message, $throwable) } |
| } |
| |
| def fatalMarkerObject(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL, $marker)) $underlying.fatal($marker, $message) } |
| } |
| |
| def fatalMarkerObjectThrowable(underlying: Expr[Logger], marker: Expr[Marker], message: Expr[AnyRef], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| '{ if ($underlying.delegate.isEnabled(Level.FATAL, $marker)) $underlying.fatal($marker, $message, $throwable) } |
| } |
| |
| def logCseq(underlying: Expr[Logger], level: Expr[Level], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgs(underlying, level, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def logCseqThrowable(underlying: Expr[Logger], level: Expr[Level], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMessageArgsThrowable(underlying, level, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| def logMarkerCseq(underlying: Expr[Logger], level: Expr[Level], marker: Expr[Marker], message: Expr[CharSequence])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgs(underlying, level, marker, messageFormat, Expr.ofSeq(args)) |
| } |
| |
| def logMarkerCseqThrowable(underlying: Expr[Logger], level: Expr[Level], marker: Expr[Marker], message: Expr[CharSequence], |
| throwable: Expr[Throwable])(using Quotes): Expr[Unit] = { |
| val (messageFormat, args) = deconstructInterpolatedMessage(message) |
| logMarkerMessageArgsThrowable(underlying, level, marker, messageFormat, Expr.ofSeq(args), throwable) |
| } |
| |
| private def logMessageArgs(underlying: Expr[Logger], level: Expr[Level], message: Expr[CharSequence], |
| args: Expr[Seq[Any]]) (using Quotes) = { |
| val anyRefArgs = formatArgs(args) |
| if(anyRefArgs.isEmpty) |
| '{ if ($underlying.delegate.isEnabled($level)) $underlying.logMessage($level, null, ${charSequenceExprToStringExpr(message)}, null) } |
| else if(anyRefArgs.length == 1) |
| '{ if ($underlying.delegate.isEnabled($level)) $underlying.delegate.log($level, ${charSequenceExprToStringExpr(message)}, ${anyRefArgs.head}) } |
| else |
| '{ if ($underlying.delegate.isEnabled($level)) $underlying.delegate.log($level, ${charSequenceExprToStringExpr(message)}, ${Expr.ofSeq(anyRefArgs)}*) } |
| } |
| |
| private def logMessageArgsThrowable(underlying: Expr[Logger], level: Expr[Level], message: Expr[CharSequence], |
| args: Expr[Seq[Any]], throwable: Expr[Throwable]) (using Quotes) = { |
| val anyRefArgs = formatArgs(args) |
| if(anyRefArgs.isEmpty) |
| '{ if ($underlying.delegate.isEnabled($level)) $underlying.logMessage($level, null, ${charSequenceExprToStringExpr(message)}, $throwable) } |
| else if(anyRefArgs.length == 1) |
| '{ if ($underlying.delegate.isEnabled($level)) $underlying.delegate.log($level, ${charSequenceExprToStringExpr(message)}, ${anyRefArgs.head}, $throwable) } |
| else { |
| val extendedArgs = anyRefArgs :+ throwable |
| '{ if ($underlying.delegate.isEnabled($level)) $underlying.delegate.log($level, ${charSequenceExprToStringExpr(message)}, ${Expr.ofSeq(extendedArgs)}*) } |
| } |
| } |
| |
| private def logMarkerMessageArgs(underlying: Expr[Logger], level: Expr[Level], marker: Expr[Marker], message: Expr[CharSequence], |
| args: Expr[Seq[Any]]) (using Quotes) = { |
| val anyRefArgs = formatArgs(args) |
| if(anyRefArgs.isEmpty) |
| '{ if ($underlying.delegate.isEnabled($level, $marker)) $underlying.logMessage($level, $marker, ${charSequenceExprToStringExpr(message)}, null) } |
| else if(anyRefArgs.length == 1) |
| '{ if ($underlying.delegate.isEnabled($level, $marker)) $underlying.delegate.log($level, $marker, ${charSequenceExprToStringExpr(message)}, ${anyRefArgs.head}) } |
| else |
| '{ if ($underlying.delegate.isEnabled($level, $marker)) $underlying.delegate.log($level, $marker, ${charSequenceExprToStringExpr(message)}, ${Expr.ofSeq(anyRefArgs)}*) } |
| } |
| |
| private def logMarkerMessageArgsThrowable(underlying: Expr[Logger], level: Expr[Level], marker: Expr[Marker], |
| message: Expr[CharSequence], args: Expr[Seq[Any]], throwable: Expr[Throwable]) (using Quotes) = { |
| val anyRefArgs = formatArgs(args) |
| if(anyRefArgs.isEmpty) |
| '{ if ($underlying.delegate.isEnabled($level, $marker)) $underlying.logMessage($level, $marker, ${charSequenceExprToStringExpr(message)}, $throwable) } |
| else if(anyRefArgs.length == 1) |
| '{ if ($underlying.delegate.isEnabled($level, $marker)) $underlying.delegate.log($level, $marker, ${charSequenceExprToStringExpr(message)}, ${anyRefArgs.head}, $throwable) } |
| else { |
| val extendedArgs = anyRefArgs :+ throwable |
| '{ if ($underlying.delegate.isEnabled($level, $marker)) $underlying.delegate.log($level, $marker, ${charSequenceExprToStringExpr(message)}, ${Expr.ofSeq(extendedArgs)}*) } |
| } |
| } |
| |
| /** Checks whether `message` is an interpolated string and transforms it into LOG4J string interpolation. */ |
| private def deconstructInterpolatedMessage(message: Expr[CharSequence])(using Quotes): (Expr[String], Seq[Expr[Any]]) = { |
| import quotes.reflect.* |
| import util.* |
| |
| message.asTerm match{ |
| case Inlined(_, _, Apply(Select(Apply(Select(Select(_, "StringContext"), _), messageNode), _), argumentsNode)) => |
| val messageTextPartsOpt: Option[List[String]] = |
| messageNode.collectFirst{ |
| case Typed(Repeated(ls, _), _) => |
| ls.collect{ case Literal(StringConstant(s)) => s} |
| } |
| val argsOpt: Option[List[Term]] = |
| argumentsNode.collectFirst { |
| case Typed(Repeated(ls, _), _) => ls |
| } |
| |
| (messageTextPartsOpt, argsOpt) match{ |
| case (Some(messageTextParts), Some(args)) => |
| val format = messageTextParts.iterator |
| // Emulate standard interpolator escaping |
| .map(StringContext.processEscapes) |
| // Escape literal log4j format anchors if the resulting call will require a format string |
| .map(str => if (args.nonEmpty) str.replace("{}", "\\{}") else str) |
| .mkString("{}") |
| |
| val formatArgs = args.map(_.asExpr) |
| |
| (Expr(format), formatArgs) |
| case _ => |
| (charSequenceExprToStringExpr(message), Seq.empty) |
| } |
| case _ => (charSequenceExprToStringExpr(message), Seq.empty) |
| } |
| } |
| |
| private def formatArgs(args: Expr[Seq[Any]])(using q: Quotes): Seq[Expr[Object]] = { |
| import quotes.reflect.* |
| import util.* |
| |
| args.asTerm match { |
| case p@Inlined(_, _, Typed(Repeated(v, _),_)) => |
| v.map{ |
| case t if t.tpe <:< TypeRepr.of[AnyRef] => t.asExprOf[Object] |
| case t => '{${t.asExpr}.asInstanceOf[Object]} |
| } |
| case Repeated(v, _) => |
| v.map{ |
| case t if t.tpe <:< TypeRepr.of[Object] => t.asExprOf[Object] |
| case t => '{${t.asExpr}.asInstanceOf[Object]} |
| } |
| case _ => Seq.empty |
| } |
| } |
| |
| private def charSequenceExprToStringExpr(expr: Expr[CharSequence])(using Quotes): Expr[String] = expr match { |
| case '{ $cs } => Expr(cs.toString) |
| } |
| } |