<?xml version="1.0" encoding="utf-8"?>
<!-- 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
-->
<?xml-stylesheet type="text/xsl" href="https://mbien.dev/roller-ui/styles/rss.xsl" media="screen"?><rss version="2.0" 
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom" >
<channel>
  <title>Michael Bien&apos;s Weblog</title>
  <link>https://mbien.dev/blog/</link>
    <atom:link rel="self" type="application/rss+xml" href="https://mbien.dev/blog/feed/entries/rss?tags=jbang" />
  <description>don&apos;t panic</description>
  <language>en-us</language>
  <copyright>Copyright 2024</copyright>
  <lastBuildDate>Sat, 24 Aug 2024 07:57:58 +0000</lastBuildDate>
  <generator>Apache Roller 6.1.4</generator>
  <item>
    <guid isPermaLink="true">https://mbien.dev/blog/entry/jfrlog-commandline-tools</guid>
    <title>Formatting JFR Events with J&apos;Bang [and JFRLog]</title>
    <dc:creator>mbien</dc:creator>
    <link>https://mbien.dev/blog/entry/jfrlog-commandline-tools</link>
    <pubDate>Wed, 28 Oct 2020 22:29:29 +0000</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>jbang</category>
    <category>jfr</category>
    <category>logging</category>
    <category>tools</category>
<description>&lt;p&gt;
Once &lt;a href=&quot;https://github.com/mbien/JFRLog/&quot;&gt;JFRLog&lt;/a&gt; stored all logs as events in JFR records, you might want to read them out again for inspection and maybe even in an easy readable format which resembles classic log files a bit more.
&lt;/p&gt;
&lt;p&gt;
For this I wrote the &lt;a href=&quot;https://github.com/mbien/JFRLog/blob/master/cli/src/main/java/dev/mbien/jfrlog/cli/JFRPrint.java&quot;&gt;JFRPrint&lt;/a&gt; utility which was originally a single-file java program (&lt;a href=&quot;//mbien.dev/blog/entry/cleaning-bash-history-using-a&quot;&gt;SFJP&lt;/a&gt;) but can now be used as &lt;a href=&quot;https://github.com/jbangdev/jbang/&quot;&gt;jbang&lt;/a&gt; script. The utility can format any JFR event, not only log messages.
&lt;/p&gt;

&lt;h3&gt;setup and example&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;
# add the catalog to jbang
$ jbang catalog add jfrlog https://github.com/mbien/JFRLog/blob/master/cli/jbang-catalog.json

# define a log pattern
$ MSG_PATTERN=&quot;{eventName,0d,C} {startTime,dt:yyyy-MM-dd HH:mm:ss.SSS}\
 [{eventThread.javaName}] {origin,1d}: {message} {throwable,o,n}&quot;

# print jfr records using the pattern
$ jbang jfrprint 10h log.* &quot;$MSG_PATTERN&quot; dump.jfr
INFO 2020-09-30 16:12:42.458 [main] jfrlogtest.LogTest: Hello There!
INFO 2020-09-30 16:12:42.460 [main] jfrlogtest.LogTest: 1 2 3 test 
WARN 2020-09-30 16:12:42.461 [main] jfrlogtest.LogTest: don&apos;t panic 
java.lang.IllegalArgumentException: test, please ignore
	at dev.mbien.jfrlogtest.LogTest.main(LogTest.java:12)
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Usage is as follows:
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;
jfrprint timespan event_name pattern [jfr_record_file | jfr_repository_folder]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;code&gt;timespan&lt;/code&gt; can be set to only print events which happened after now-timespan. The util will print all events matching &lt;code&gt;event_name&lt;/code&gt; (supports * wildcard as postfix) if a JFR record is passed as an argument. If it is a repository folder however, it is going to behave similar to &lt;code&gt;tail -f&lt;/code&gt; and will stream all upcoming events from the live JFR repository.
&lt;/p&gt;
&lt;p&gt;
To print the usage and more examples simply type:
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;
jbang jfrprint help
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;message pattern&lt;/h3&gt;
&lt;p&gt;
&lt;code&gt;{fieldName, option1, option2, ..}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The message pattern format fairly simple. The curly brace blocks are replaced with the event field defined by &lt;code&gt;fieldName&lt;/code&gt;. Printing the name of the event thread for example becomes &lt;code&gt;{eventThread.javaName}&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Options can be appended in a coma separated list after &lt;code&gt;fieldName&lt;/code&gt;.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dt:&lt;/code&gt; prefix defines a date-time format and supports everything what &lt;a href=&quot;https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/time/format/DateTimeFormatter.html&quot;&gt;DateTimeFormatter.ofPattern()&lt;/a&gt; is able to parse&lt;/li&gt;
&lt;li&gt;&lt;code&gt;c&lt;/code&gt; sets the String to lower case, &lt;code&gt;C&lt;/code&gt; to upper case&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[0-n]d&lt;/code&gt; defines how many dots you want to see. &lt;code&gt;0d&lt;/code&gt; would format &quot;log.Warn&quot; to &quot;Warn&quot;. &lt;code&gt;1d&lt;/code&gt; formats &quot;foo.bar.Bazz&quot; to &quot;bar.Bazz&quot;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;o&lt;/code&gt; stands for optional and won&apos;t print anything if the field is null. This can be useful for printing exceptions when combined with &lt;code&gt;n&lt;/code&gt; which adds a new line before the field&lt;/li&gt;
&lt;li&gt;for more options check the &lt;a href=&quot;https://github.com/mbien/JFRLog/blob/master/cli/src/main/java/dev/mbien/jfrlog/cli/JFRPrint.java#L333&quot;&gt;source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;code&gt;{...}&lt;/code&gt; is a special token which will print all fields which haven&apos;t been printed yet. This is especially useful for events which aren&apos;t log messages which might have unknown fields.
&lt;/p&gt;
&lt;p&gt;
The following pattern will print all events with all their fields which happened in the last hour:
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;
jfrprint 1h * &quot;{eventName} {startTime} {...}&quot; record.jfr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Note: if no pattern is provided the output will match the multi-line output of OpenJDK&apos;s &lt;code&gt;jfr print&lt;/code&gt; CLI tool which is also the same format as used in &lt;code&gt;jdk.jfr.Event::toString()&lt;/code&gt;.
&lt;/p&gt;

&lt;h3&gt;it is still very basic&lt;/h3&gt;
&lt;p&gt;
I wrote it originally as SFJP and tried to keep everything as simple and concise as possible. But since it is now set up as as jbang &quot;script&quot;, it would allow to make the CLI experience a bit nicer - which i might do in future ;)
&lt;/p&gt;
&lt;p&gt;
Let me know if you find it useful or want to see a particular feature.
&lt;/p&gt;</description>  </item>
</channel>
</rss>