简体   繁体   English

用scala整理日志?

[英]unclutter logging with scala?

I like scala as it can help me have cleaner code. 我喜欢scala,因为它可以帮助我获得更简洁的代码。

However while logging i feel my code gets cluttered... 但是在登录时,我感到我的代码混乱了……

def myFunc(args) = {
  log.trace("entering myfunc, args are ... ")
  val result = doSomething()
  log.info("I really want to print that result which is {}", result)
  log.trace("exiting myfunc result {}", result)
  result
}

as you can see instead of just calling 如您所见,而不仅仅是打电话

def myFunc(args) = doSoemthing

I needed to split the result into a var so that i can first log it and only then return it. 我需要将结果拆分为var以便我可以首先将其记录下来,然后再返回。 now that was a simple use case in more complex use cases I have more loggings in my methods, some info some debug things become more complex and code becomes much more cluttered due to logging.. 现在这是一个更简单的用例,在更复杂的用例中,我的方法中有更多的日志记录,一些info一些debug问题变得更加复杂,并且由于日志记录,代码变得更加cluttered

while I could wrap my method with another method which would add logging on entry and exit this would make my code more complex so i'm looking for a very clean logging solution not focusing only on method entry and exit (I dont want to use AOP because it makes code also more compelx and hard to understand). 虽然我可以用另一种方法包装我的方法,这将增加进入和退出的日志记录,这会使我的代码更加复杂,所以我正在寻找一种非常干净的日志记录解决方案,而不仅关注方法的进入和退出(我不想使用AOP因为它使代码也更加复杂且难以理解)。

how to unclutter code while still having code simple and easy to understand with powerful logging? 如何在保持强大功能的日志的同时使代码简单易懂的同时使代码混乱? (solution not invented yet?) or is there a true clean solution? (尚未发明解决方案?)还是有一个真正的干净解决方案?

First of all, nothing prevent you from defining that result as val , not var . 首先,没有什么可以阻止您将结果定义为val ,而不是var Next, there is such thing as kestrel combinator (see also linked answer specifically on logging topic), which is usually used for such purporses: 接下来,有诸如茶est组合器之类的东西(另请参见有关日志记录主题的链接答案),通常用于以下用途:

def myFunc(args) = {
  log.trace("entering myfunc, args are ... ")
  doSomething().tap { result => 
    log.info("I really want to print that result which is {}", result)
    log.trace("exiting myfunc result {}", result)
  }
}

Next, I do believe there is similar to AOP methods, like scala virtualized (which allow you to pimp basic language syntax), but it feels like huge overkill to me, I guess you can roll out a set of helpers and use them as: 接下来,我确实相信有类似于AOP的方法,例如scala虚拟化 (允许您使用基本语言语法),但是对我来说感觉像是过大了,我想您可以推出一组帮助程序并将其用作:

traced(foo) { x => 
  myFunc(x) 
}

so input and output will be logged 因此输入和输出将被记录

This question has been answered and accepted already, but there's another solution in the limited context of debugging; 这个问题已经得到回答和接受,但是在有限的调试环境中还有另一种解决方案。 and it can be probably combined with existing solutions. 并且可以与现有解决方案结合使用。

Full disclosure: I've developed Scart , so I am biased; 全面披露:我开发了Scart ,因此我有偏见; whether or not it's elegant is a question of taste! 它是否优雅是品味的问题!

If you want to perform tracing , as opposed to logging , ie emit debugging info for developers and do not want that in the deployed product, you can try Scart's Expression Tracers. 如果要执行跟踪 (而不是记录)即为开发人员发出调试信息,并且不希望在已部署的产品中使用该信息,则可以尝试Scart的Expression Tracers。

Actually, they came to existence for the reason you mentioned; 实际上,它们之所以存在是因为您提到的原因。 to some extent they can be inserted on the right side of the source code, therefore the clutter doesn't disappear but is less intrusive. 在某种程度上,它们可以插入到源代码的右侧,因此,杂波不会消失,但干扰较小。 At least that works for me. 至少对我有用。

I haven't tried the following, but in your use case that may look like: 我没有尝试以下操作,但是在您的用例中,可能看起来像:

def myFunc(args) = {                             
  val result = doSomething(args)
  log.info("I really ... which is {}", result)
  result                                             e_++: s"myFunc($args)"
}

I left the log info, otherwise: 我留下了日志信息,否则:

def myFunc(args) = doSomething(args)                 e_++: s"myFunc($args)"

or rather (Scart uses macros; the compiler gives a warning if this trace is off): 或者更确切地说(Scart使用宏;如果关闭此跟踪,则编译器会发出警告):

def myFunc(args) =                                   s"myFunc($args)".e_++:
{
  doSomething(args)
}

You'll note that I didn't write lengthy trace strings, but Scart automatically adds information such as class, method names, line# etc. Since it's for debugging, I personally refer to those and don't need to write very long strings. 您会注意到,我没有编写冗长的跟踪字符串,但是Scart自动添加了诸如类,方法名称,行号等信息。由于它是用于调试的,因此我个人引用了这些信息,不需要编写很长的字符串。

There are more options, eventually I ought to document them all. 还有更多选择,最终我应该将它们全部记录下来。

Also, Scart doesn't require a logger to operate. 另外,Scart不需要记录器即可操作。 In order to output its traces within logs, you'll have to designate a printer function that uses a logger (in the Scart settings object Settings ) which is of type String => Unit . 为了在日志中输出其跟踪,您必须指定一个printer功能,该功能使用String => Unit类型的记录器(在Scart设置object Settings )。

Cheers. 干杯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM