java 异常堆栈字符串_带有堆栈跟踪过滤,静默字符串解析和版本比较的开源Java库...

java 异常堆栈字符串

Here is the Github link 这是Github链接 Javadoc online is available here 在线Javadoc可在此处获得

Also, this library is available on Maven Central. Here are the Maven artifacts (the version 1.5.1.0 is the latest at the time of writing of this article but might change in the future. To check for the latest version search for artifact «MgntUtils» at http://search.maven.org/):

此外,该库在Maven Central上可用。 这是Maven工件(在撰写本文时,最新版本为1.5.1.0,但将来可能会更改。要检查最新版本,请在http://search.maven中搜索工件«MgntUtils» 。 org / ):

<dependency>
     <groupId>com.github.michaelgantman</groupId>
     <artifactId>MgntUtils</artifactId>
     <version>1.5.1.0</version>
</dependency>

 <dependency>
     <groupId>com.github.michaelgantman</groupId>
     <artifactId>MgntUtils</artifactId>
     <version>1.5.1.0</version>
     <classifier>javadoc</classifier>
</dependency>

<dependency>
     <groupId>com.github.michaelgantman</groupId>
     <artifactId>MgntUtils</artifactId>
     <version>1.5.1.0</version>
     <classifier>sources</classifier>
</dependency>

Below is just a short explanation of what is there. The library comes with a nicely written (I hope) JavaDoc with a detailed description. So here is the list of features:

以下只是其中的简短说明。 该库随附了写得很好(希望如此)的JavaDoc,并带有详细描述。 因此,这里是功能列表:

Stacktrace噪声滤波器 (Stacktrace noise filter)

In my experience, this feature was the most generic and useful for me. Stacktrace is a lifesaver when debugging or trying to figure out what went wrong in your application. However, when working with logs on the server side you can come across huge stacktrace that contains the longest useless tail of various frameworks and Application Server related packages. And somewhere in this pile, there are several lines of a relevant trace and they may be in different segments separated by useless information. It becomes a nightmare to search for a relevant stuff. Here is a link that describes the same problem with real-life examples (not for the fainthearted ) https://dzone.com/articles/filtering-stack-trace-hell. So In my library, There is a class is called TextUtils and it has method getStacktrace() with several overloaded signatures. It takes a Throwable instance and allows to set a package prefix of the packages that are relevant.

以我的经验,此功能对我来说是最通用和有用的。 在调试或尝试找出应用程序中出了什么问题时,Stacktrace是一个救生器。 但是,在服务器端使用日志时,您会遇到巨大的stacktrace,其中包含各种框架和与Application Server相关的软件包中最长的无用的尾巴。 在该堆中的某处,有几条相关的迹线,它们可能位于无用的信息所分隔的不同段中。 寻找相关内容成为噩梦。 这是一个描述真实示例中相同问题的链接(不适用于胆小的人) https://dzone.com/articles/filtering-stack-trace-hell 。 因此,在我的库中,有一个名为TextUtils的类,它具有带有几个重载签名的getStacktrace()方法。 它采用Throwable实例,并允许设置相关软件包的软件包前缀。

Also, the same utility (starting from version 1.5.0.3) has method getStacktrace() that takes CharSequence interface instead of Throwable and thus allows to filter and shorten stacktrace stored as a string the same way as a stacktrace extracted from Throwable. So, essentially stacktraces could be filtered «on the fly» at run time or later on from any text source such as a log. (Just to clarify — the utility does not support parsing and modifying the entire log file. It supports filtering just a stacktrace that as passed as a String. So if anyone wants to filter exceptions in the log file they would have to parse the log file and extract stacktrace(s) as separate strings and then can use this utility to filter each individual stacktrace).

同样,相同的实用程序(从1.5.0.3版开始)具有方法getStacktrace() ,该方法采用CharSequence接口而不是Throwable,因此可以过滤和缩短作为字符串存储的堆栈跟踪,方法与从Throwable提取的堆栈跟踪相同。 因此,基本上,堆栈跟踪可以在运行时“即时”过滤,也可以稍后从任何文本源(如日志)中过滤。 (请澄清一下。该实用程序不支持解析和修改整个日志文件。它仅支持过滤作为String传递的stacktrace。因此,如果有人想过滤日志文件中的异常,则必须解析日志文件。并提取stacktrace作为单独的字符串,然后可以使用此实用程序过滤每个单独的stacktrace)。

Here is a usage example. Let's say your company's code always resides in packages that start with «com.plain.*» So you set such a prefix and do this

这是一个用法示例。 假设您公司的代码始终位于以«com.plain。*»开头的软件包中,因此您可以设置这样的前缀并执行此操作

logger.info(TextUtils.getStacktrace(e,true,"com.plain."));

this will filter out very smartly all the useless parts of the trace leaving you with very concise stacktrace. Also, I found it very convenient to pre-set the prefix and then just use the convenience method

这将非常巧妙地过滤掉跟踪中所有无用的部分,从而为您提供非常简洁的stacktrace。 另外,我发现预先设置前缀然后使用便捷方法非常方便

TextUtils.getStacktrace(e);

It will do the same. To preset the prefix just use method

它将执行相同的操作。 预设前缀只需使用方法

setRelevantPackage("com.plain.");

If you would like to pre-set this value by configuration then starting with the library version 1.1.0.1 you can set Environment Variable "

如果您想通过配置来预先设置此值,则从库版本1.1.0.1开始,可以设置“环境变量”

MGNT_RELEVANT_PACKAGE (MGNT_RELEVANT_PACKAGE)

" or System Property "

“或系统属性”

mgnt.relevant.package (mgnt.relevant.package)

" to value "

“重视”

com.plain." and the property will be set to that value without you invoking method 抱怨。 ”,并且无需调用方法 TextUtils.setRelevantPackage(«com.plain.»); explicitly in your code. Note that System property value would take precedence over the environment variable if both were set. Just a reminder that with System property you can add it in your command line using -D flag: TextUtils.setRelevantPackage(«com.plain。»);即可将该属性设置为该值。请注意,如果同时设置了系统属性值,则系统属性值将优先于环境变量。提醒您,使用System属性,您可以使用-D标志在命令行中添加它:

"-Dmgnt.relevant.package=com.plain."

“ -Dmgnt.relevant.package = com.plain。”

Also, if you use a version earlier then 1.1.0.1 of this library or don't want to use Environment variable or system property mentioned above and you are using Spring environment you can preset the prefix by adding the following segment to your Spring configuration:

另外,如果您使用的库版本早于1.1.0.1,或者不想使用上述环境变量或系统属性,并且您正在使用Spring环境,则可以通过在Spring配置中添加以下段来预设前缀:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
     <property name="targetClass" value="com.mgnt.utils.TextUtils"/>
     <property name="targetMethod" value="setRelevantPackage"/>
     <property name="arguments" value="com.plain."/>
</bean>

Javadoc explains everything in detail. But here is a little teaser: you will get a following stacktrace:

Javadoc详细解释了所有内容。 但是这里有一个小提示:您将获得以下堆栈跟踪:

at com.plain.BookService.listBooks()
at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
...
at com.plain.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
...
at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks()
at com.plain.web.BookController.listBooks()

instead of

代替

at com.plain.BookService.listBooks()
at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed()
at com.plain.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
at sun.reflect.NativeMethodAccessorImpl.invoke()
at sun.reflect.DelegatingMethodAccessorImpl.invoke()
at java.lang.reflect.Method.invoke()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod()
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept()
at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks()
at com.plain.web.BookController.listBooks()

静默字符串解析为整数,长整数等 (Silent String parsing into Integer, Long, etc)

The same class TextUtils provides methods to parse String silently (without exception ever being thrown) into types of Double, Long, Integer, Short and Byte. The methods are called parseStringToLong() parseStringToInteger() etc. They all take 4 arguments:

相同的TextUtils类提供了一些方法,可将String静默地解析String(不会抛出异常),分为Double,Long,Integer,Short和Byte类型。 这些方法称为parseStringToLong() parseStringToInteger()等。它们全部采用4个参数:

  1. A String to be parsed

    要解析的字符串
  2. An implementation of Number (Double, Long, Integer, Short or Byte) to serve as default value if any parsing problem occurred

    如果发生任何解析问题,则将Number(双精度,长整数,整数,短整数或字节)的实现用作默认值
  3. A String to be printed as an error message into the log if the first argument is null (may be null, and then no error is printed)

    如果第一个参数为null(可以为null,则不打印错误),则作为错误消息打印到日志中的String
  4. A String to be printed as an error message if NumberFormatException occurred (may be null, and then no error is printed)

    如果发生NumberFormatException,则将作为错误消息打印的字符串(可以为null,然后不打印错误)

解析字符串到时间间隔 (Parsing String to Time Interval)

In the same class TextUtils, there is a method parseStringToTimeInterval(String value). This method parses a string that is expected to hold some time interval value — a numeric value with optional time unit suffix. For example, string «38s» will be parsed as 38 seconds, «24m» — 24 minutes «4h» — 4 hours, «3d» — 3 days and «45» as 45 milliseconds. Supported suffixes are "

在同一类TextUtils中 ,有一个方法parseStringToTimeInterval(String value) 。 此方法解析预期包含某个时间间隔值的字符串-一个带有可选时间单位后缀的数字值。 例如,字符串“ 38s”将被解析为38秒,«24m»— 24分钟«4h»— 4小时,«3d»— 3天和«45»被解析为45毫秒。 支持的后缀为“

s (s)

" for seconds, "

“几秒钟,”

(m)

" for minutes, "

“几分钟,”

H (h)

" for hours and "

“几个小时,然后”

d (d)

" for days. String without a suffix is considered to hold a value in milliseconds. Suffixes are case insensitive. If provided String contains an unsupported suffix or holds negative numeric value or zero or holds a non-numeric value — then IllegalArgumentException is thrown. This method returns TimeInterval class — a class also defined in this library. Essentially, it holds two properties with relevant getters and setters: long «value» and java.util.concurrent.TimeUnit. But in addition to getters and setters this class has methods

“,以天为单位。不带后缀的字符串将被视为持有以毫秒为单位的值。后缀不区分大小写。如果提供的字符串包含不支持的后缀或具有负数字值或零或具有非数字值,则抛出IllegalArgumentException。方法返回TimeInterval类(该类也在此库中定义),基本上,它具有两个具有相关getter和setter的属性:long«value»和java.util.concurrent.TimeUnit。但是,除了getter和setters之外,此类还具有方法

toMillis(), toMillis()toSeconds(), toSeconds()toMinutes(), toMinutes()toHours() toHours() toDays(). Those methods return long value in specified time scale (The same way as corresponding methods in class toDays() 。 这些方法在指定的时间范围内返回long值(与类 java.util.concurrent.TimeUnit) java.util.concurrent.TimeUnit中的相应方法相同)

This method may be very useful for parsing time interval properties such as timeouts or waiting periods from configuration files. It eliminates unneeded calculations from different time scales to milliseconds back and forth. Consider that you have a

此方法对于解析时间间隔属性(例如,超时或配置文件中的等待时间)可能非常有用。 它消除了从不同时间范围到来回毫秒之间不必要的计算。 考虑你有一个

methodInvokingInterval (methodInvokingInterval)

property that you need to set for 5 days. So in order to set the milliseconds value, you will need to calculate that 5 days is 432000000 milliseconds (obviously not an impossible task but annoying and error-prone) and then anyone else who sees the value 432000000 will have to calculate it back to 5 days which is frustrating. But using this method you will have a property value set to «5d» and invoking the code

您需要设置5天的属性。 因此,为了设置毫秒值,您将需要计算5天为432000000毫秒(显然这不是不可能完成的任务,但很烦人且容易出错),然后看到432000000值的其他任何人都必须将其计算回5令人沮丧的日子。 但是使用这种方法,您会将属性值设置为«5d»,并调用代码

long milliseconds = TextUtils.parsingStringToTimeInterval("5d").toMillis();

will solve your conversion problem. Obviously, this is not an overly complex feature, but it could add simplicity and clarity in your configuration files and save some frustration and «stupid» miscalculation into milliseconds bugs.

将解决您的转换问题。 显然,这并不是一个过于复杂的功能,但是它可以在您的配置文件中增加简洁性和清晰度,并将一些挫败感和“愚蠢”错误计算结果保存为毫秒级错误。

比较版本 (Compare Versions)

This utility allows to convert String to version and vise-versa and to compare versions and version ranges properly. Often if you need to compare versions you just compare Strings. So lets say version «1.5.3» will be greater than version «1.3.1». However, if you will compare Strings «1.4.2» and «1.12.3» the String «1.4.2» will erroneously be greater. So this Utility takes care of such a problem and in addition, introduces VersionRange class and allows operations on version ranges. (See methods compareVersions in class TextUtils and class VersionRange)

此实用程序允许将String转换为版本,反之亦然,并正确比较版本和版本范围。 通常,如果您需要比较版本,则只需比较字符串。 因此,可以说版本“ 1.5.3”将大于版本“ 1.3.1”。 但是,如果将字符串«1.4.2»和«1.12.3»进行比较,则字符串«1.4.2»将错误地更大。 因此,该实用程序可以解决此类问题,此外,它还引入了VersionRange类,并允许对版本范围进行操作。 (参见类文本实用程序和类VersionRange方法compareVersions)

字符串Unicode转换器 (String Unicode converter)

Class StringUnicodeEncoderDecoder has methods that can convert a String (in any language) into a sequence of Unicode characters and vise-versa. For example, a string «Hello World» will be converted into

StringUnicodeEncoderDecoder具有可以将String(以任何语言)转换为Unicode字符序列的方法,反之亦然。 例如,字符串“ Hello World”将被转换为

"\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064"

“ \ u0048 \ u0065 \ u006c \ u006c \ u006f \ u0020 \ u0057 \ u006f \ u0072 \ u006c \ u0064

and may be restored back.

并可以恢复原状。

生命周期管理(自实例工厂) (Lifecycle management (Self-instantiating factories))

This feature is a package that contains some small infrastructure that simplifies and automates working with Factories that provide concrete implementations of an Interface. The package contains just 2 classes: BaseEntityFactory and BaseEntity. In short, what this infrastructure does is that if you create a factory that extends BaseEntityFactory and some Interface with all its concrete implementations extending BaseEntity then each of your concrete implementation class instances will be automatically inserted into your factory. You won't have to worry about how and when to populate your factory. The infrastructure will do it for you when the constructor of your concrete implementation class is invoked. So all you will have to do is to create any number of concrete implementation classes and make sure that for each one constructor is invoked. After that, you can use your factory to get any of your concrete implementation classes anywhere in your code. This is a short explanation. There are a few more details but not that many. For a detailed description of this package please refer to Javadoc API of package

此功能是一个软件包,其中包含一些小型基础结构,这些基础结构可简化和自动化与提供接口具体实现的工厂的工作。 该软件包仅包含2个类: BaseEntityFactoryBaseEntity 。 总之,这是什么做基础是,如果你创建一个工厂,扩展BaseEntityFactory和一些接口与所有的具体实现扩展BaseEntity然后每个具体的实现类的实例将被自动插入到你的工厂。 您不必担心如何以及何时填充工厂。 调用具体实现类的构造函数时,基础结构将为您完成此操作。 因此,您要做的就是创建任意数量的具体实现类,并确保为每个构造函数都调用一个。 之后,您可以使用工厂在代码中的任何位置获取任何具体的实现类。 这是一个简短的解释。 还有更多细节,但没有那么多。 有关此软件包的详细说明,请参阅该软件包的Javadoc API

com.mgnt.lifecycle.management (com.mgnt.lifecycle.management)

description. Also, the source code contains package com.mgnt.lifecycle.management.example that holds well commented and detailed code example on how to use this feature.

描述。 此外,源代码包含com.mgnt.lifecycle.management.example软件包,其中包含有关如何使用此功能的注释清楚且详细的代码示例。

As for practical usage, I found it very useful for the Spring framework. Remember that Spring instantiates all it's defined beans during its initialization. So within the Spring context, if we simply declare our concrete implementations as Spring beans, Spring would instantiate them for us, thus initializing their factory automatically. This could be very convenient. Imagine that you have some bean that has a property of the type of user-defined Interface that has several implementations, but which actual implementation would be needed is determined at runtime. So at that time, you can use method getInstance(java.lang.String) of your Factory to access needed implementation. This will allow you not to inject ALL your concrete instantiations into your bean and you won't have to use Spring BeanFactory to access a Spring defined bean as that would violate non-intrusiveness of Spring (meaning you can write components which have no dependency on Spring). Also, If at some later stage you will need to add more concrete implementations, all you will have to do is to add your implementation classes to your code and declare them to be Spring beans. The rest will be done by Spring and this infrastructure!

至于实际用法,我发现它对于Spring框架非常有用。 请记住,Spring在初始化期间会实例化所有它定义的bean。 因此,在Spring上下文中,如果我们简单地将具体实现声明为Spring Bean,Spring将为我们实例化它们,从而自动初始化它们的工厂。 这可能非常方便。 想象一下,您有一些具有用户定义接口类型的属性的Bean,该属性具有多个实现,但是实际需要哪种实现是在运行时确定的。 因此,那时,您可以使用Factory的getInstance(java.lang.String)方法访问所需的实现。 这将使您不必将所有具体实例都注入到bean中,并且不必使用Spring BeanFactory来访问Spring定义的bean,因为这会违反Spring的非介入性(这意味着您可以编写不依赖于Spring的组件)弹簧)。 另外,如果在以后的某个阶段需要添加更多具体的实现,那么您要做的就是将实现类添加到代码中,并将它们声明为Spring bean。 其余的工作将在Spring和此基础架构中完成!

文件实用程序 (File Utils)

This utility allows to read a file as a String with or without specifying character set or just read it as a byte array. This utility uses nio package and Buffers for faster performance. Max file size for this Utility is 2G.

使用此实用程序,可以在指定或不指定字符集的情况下将文件读取为字符串,或者仅将其读取为字节数组。 该实用程序使用nio软件包和Buffers来提高性能。 该实用程序的最大文件大小为2G。

时间利用率 (Time Util)

This is just a single convenience method that provides the same functionality as Thread.sleep() but it is silent. I.e. it «swallows» IterruptedException. Also, it takes 2 arguments: time to sleep and measurement unit. So instead of

这只是一个便捷方法,提供与Thread.sleep()相同的功能,但它是无声的。 即它“吞下” IterruptedException。 同样,它需要两个参数:睡眠时间和度量单位。 所以代替

try {
     Thread.sleep(2000);
} catch (InterruptedException ie) {
}

You can just write:

您可以这样写:

TimeUtils.sleepFor(2, TimeUnit.SECONDS);

I thought it was cute

我以为很可爱

So this is it. Feel free to download this library. It comes with MIT license — one of the most permissive licenses I know of. Source code, Javadoc and binary version is available at the link above. The code was compiled by JDK 8 but has no features of version 8 in it. It should work with java 7 most definitely, I suspect it will work with java 6 and even 5, but haven't tested it with those versions. Feel free to use it as you see fit, tell others about it if you like it and feel free to drop me a note at michael_gantman@yahoo.com if you have any feedback.

就是这样。 随意下载该库。 它带有MIT许可证-我所知道的最宽松的许可证之一。 上面的链接提供了源代码,Javadoc和二进制版本。 该代码由JDK 8编译,但是其中没有版本8的功能。 它绝对应该与Java 7一起使用,我怀疑它可以与Java 6甚至5一起使用,但是尚未在这些版本上进行过测试。 可以随意使用它,如果喜欢的话,告诉其他人,如果有任何反馈,请随时给我发邮件michael_gantman@yahoo.com。

翻译自: https://habr.com/en/post/480268/

java 异常堆栈字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值