What is the fastest way of (not) logging?
原文地址:http://www.slf4j.org/faq.html#logging_performance
SLF4J supports an advanced feature called parameterized logging which can significantly boost logging performance for disabled logging statement.
For some Logger logger, writing,
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
incurs the cost of constructing the message parameter, that is converting both integer i and entry[i] to a String, and concatenating intermediate strings. This, regardless of whether the message will be logged or not.
One possible way to avoid the cost of parameter construction is by surrounding the log statement with a test. Here is an example.
if(logger.isDebugEnabled()) {
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
This way you will not incur the cost of parameter construction if debugging is disabled for logger. On the other hand, if the logger is enabled for the DEBUG level, you will incur the cost of evaluating whether the logger is enabled or not, twice: once in debugEnabled and once in debug. This is an insignificant overhead because evaluating a logger takes less than 1% of the time it takes to actually log a statement.
Better yet, use parameterized messages
There exists a very convenient alternative based on message formats. Assuming entry is an object, you can write:
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
After evaluating whether to log or not, and only if the decision is affirmative, will the logger implementation format the message and replace the '{}' pair with the string value of entry. In other words, this form does not incur the cost of parameter construction in case the log statement is disabled.
The following two lines will yield the exact same output. However, the second form will outperform the first form by a factor of at least 30, in case of a disabled logging statement.
logger.debug("The new entry is "+entry+".");
logger.debug("The new entry is {}.", entry);
A two argument variant is also available. For example, you can write:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
If three or more arguments need to be passed, you can make use of the Object... variant of the printing methods. For example, you can write:
logger.debug("Value {} was inserted between {} and {}.", newVal, below, above);
This form incurs the hidden cost of construction of an Object[] (object array) which is usually very small. The one and two argument variants do not incur this hidden cost and exist solely for this reason (efficiency). The slf4j-api would be smaller/cleaner with only the Object... variant.
Array type arguments, including multi-dimensional arrays, are also supported.
SLF4J uses its own message formatting implementation which differs from that of the Java platform. This is justified by the fact that SLF4J's implementation performs about 10 times faster but at the cost of being non-standard and less flexible.
Escaping the "{}" pair
The "{}" pair is called the formatting anchor. It serves to designate the location where arguments need to be substituted within the message pattern.
SLF4J only cares about the formatting anchor, that is the '{' character immediately followed by '}'. Thus, in case your message contains the '{' or the '}' character, you do not have to do anything special unless the '}' character immediately follows '}'. For example,
logger.debug("Set {1,2} differs from {}", "3");
which will print as "Set {1,2} differs from 3".
You could have even written,
logger.debug("Set {1,2} differs from {{}}", "3");
which would have printed as "Set {1,2} differs from {3}".
In the extremely rare case where the the "{}" pair occurs naturally within your text and you wish to disable the special meaning of the formatting anchor, then you need to escape the '{' character with '\', that is the backslash character. Only the '{' character should be escaped. There is no need to escape the '}' character. For example,
logger.debug("Set \\{} differs from {}", "3");
will print as "Set {} differs from 3". Note that within Java code, the backslash character needs to be written as '\\'.
In the rare case where the "\{}" occurs naturally in the message, you can double escape the formatting anchor so that it retains its original meaning. For example,
logger.debug("File name is C:\\\\{}.", "file.zip");
will print as "File name is C:\file.zip".
What is the fastest way of (not) logging?的更多相关文章
- Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
学习架构探险,从零开始写Java Web框架时,在学习到springAOP时遇到一个异常: "C:\Program Files\Java\jdk1.7.0_40\bin\java" ...
- Oracle补全日志(Supplemental logging)
Oracle补全日志(Supplemental logging)特性因其作用的不同可分为以下几种:最小(Minimal),支持所有字段(all),支持主键(primary key),支持唯一键(uni ...
- Java程序日志:java.util.logging.Logger类
一.Logger 的级别 比log4j的级别详细,全部定义在java.util.logging.Level里面.各级别按降序排列如下:SEVERE(最高值)WARNINGINFOCONFIGFINEF ...
- python 学习笔记 -logging模块(日志)
模块级函数 logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root loggerlogging.debug().logging.info().lo ...
- python logging colorlog
import logging LOG_LEVEL = logging.NOTSET LOGFORMAT = "[%(log_color)s%(levelname)s] [%(log_colo ...
- [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件
本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...
- python 之 logging
#coding=utf-8 import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename ...
- Python Logging模块的简单使用
前言 日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法.本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表. 另外,Python的H ...
- python模块(shelve,xml,configparser,hashlib,logging)
1.1shelve模块 shelve 模块比pickle模块简单,只有一个open函数,返回类似字典对象,可读可写:key必须为字符串, 而值可以是python所支持的数据类型. shelve模块主要 ...
随机推荐
- leetcode 之Search in Rotated Sorted Array(三)
描述 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 ...
- Construct Binary Tree from Inorder and Postorder Traversal (&&Preorder and Inorder Traversal )——数据结构和算法的基本问题
Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume tha ...
- [实战]MVC5+EF6+MySql企业网盘实战(17)——思考2
写在前面 今天吃饭回来,突然有一个更好的想法,这里做一下记录. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实战 ...
- persistencejs:异步javascript数据库映射库
persistence.js 是一个异步的 JavaScript 对象数据库映射(ORM)框架.拥有数据库无关的独立抽象层,可轻松支持新的数据库.该软件最开始是为浏览器设计的,利用 HTML5 的 W ...
- bzoj 1100
思路:好脑洞啊... 把边和角转化为字符串,然后用反串跑kmp... #include<bits/stdc++.h> #define LL long long #define fi fir ...
- 记录自己在 cmd 中执行 jar 文件遇到的一些错误
记录自己在 cmd 中执行 jar 文件遇到的一些错误 场景: 请求接口,解析接口返回的 JSON 字符串并插入到我们的数据库里面. 情况: 项目在 eclipse 中正常运行,打成 jar 包后在 ...
- 使用自己的域名解析 cnblogs 博客
使用自己的域名解析 cnblogs 博客(博客园) 1.实现原理 用户访问 -> 阿里云解析 -> github page 跳转 -> 真实的博客地址 2.创建 github pag ...
- php实现var_dump函数
<?php class VarDump { private static $isInLoop = false; private static $buffer = false; public st ...
- ssm+RESTful bbs项目后端主要设计
小谈: 帖主妥妥的一名"中"白了哈哈哈.软工的大三狗了,也即将找工作,怀着丝丝忐忑接受社会的安排.这是第一次写博客(/汗颜),其实之前在学习探索过程中,走了不少弯路,爬过不少坑.真 ...
- Linux Shall命令入门
Linux Shall命令入门 ifconfig //查看ip信息 service network start ...