Argument processor There is a generic method withProcessor(obj)
that allows attaching arbitrary argument processors to spy configuration and some convenience methods attaching predefined processors:
Formatting strings
spy.format(dst, formatExpr)
spy.format(dst, formatExpr, maxLen)
Will evaluate formatExpr
, substitute values (fetched in the same record) and store result at slot number dst
. Format strings look like this:
"this is ${TYPE} event"
"host name: ${CTX.class.name}"
All substitution placeholders are marked with ${....}
. Inside it there is a name (interesting) event field eg. fetched by argument fetchers and optionally subsequent attributes that allow looking inside (using getters, indexing, keys etc. depending in object type - as in zorka.jmx()
function).
Another features of format strings are variants and default values, for example:
"${THIS.sConnection|THIS.wrappedQuery.sConnection:none}"
This string will try to extract sConnection
attribute from object THIS
. If it fails (ie. null
will be returned), agent will try extract wrappedConn
attribute and sConnection
from it. If it also fails, none
as default value will be used as substitution.
Adminstrator can also limit length of substitution string. This is useful in particular in trappers. For example:
"${SQL~20}"
Above substitution will limit substitution length to 20 characters. All above features can be combined, for example:
"${THIS.sqlQuery|THIS.wrapped.sqlQuery:unknown~80}"
This will try two variants, substitute unknown
string if none matches and limit whole substitution length to 80 characters.
Fetching attributes from arguments
spy.get(src, dst, attr1, attr2, ...);
This will fetch attribute chain (attr1,attr2,...)
from src
slot of passing spy records and store result into dst
slot of spy records.
Calling method of argument object
spy.call(src, dst, methodName, arg1, arg2, ...);
This will get argument at index src
, call method named methodName with arguments (arg1, arg2, ...)
and store result into dst
.
Calculating time difference between arguments
spy.tdiff(in1, in2, out);
It will take arguments from in1
and in2
, ensure that these are long integers and stores result at out
.
Storing data across method calls using ThreadLocal
Sometimes it is useful to use data grabbed from some method and use it along with other method further down call stack. The following methods can be used with thread local objects:
spy.get(dst, threadLocal, path...)
spy.put(src, threadLocal)
spy.remove(threadLocal)
Thread local object has to be declared in BSH script and is passed as threadLocal
argument to each of these methods. Method put()
stores value from slot src
in threadLocal
. Method get()
reads value from threadLocal
and stores it in slot dst
. Last method clears threadLocal
, so stored object can be garbage collected (granted there are no more references pointing to it).
Calculating checksums
Checksums are useful when some collected data pose security risk. For example JSESSIONID
should not be collected in clear text but their checksums might still be useful for debugging purposes (so administrator will be able to eg. filter requests of user session in collector UI). There are three checksums that can be calculated right now: crc32, md5 and sha1.
spy.crc32sum(dest, source)
spy.crc32sum(dest, source, limit)
spy.md5sum(dest, source)
spy.md5sum(dest, source, limit)
spy.sha1sum(dest, source)
spy.sha1sum(dest, source, limit)
Spy plugins created by those functions will take value from source
field, convert it to string, calculate checksum, convert result to hexadecimal string and store it in dest
field. If limit
argument is passed, resulting string will be cut, so at most first limit
characters will be returned.
These functions have their counterparts that calculate checksums immediately instead of creating processing plugin:
zorka.crc32sum(dest, source)
zorka.crc32sum(dest, source, limit)
zorka.md5sum(dest, source)
zorka.md5sum(dest, source, limit)
zorka.sha1sum(dest, source)
zorka.sha1sum(dest, source, limit)
Above functions can be used in spy processing code manually implemented in Bean Shell.
Timestamp to string functions
spy.strTime(dest)
spy.strTime(dest, src)
These two functions can create plugins that convert internal representation of time interval (nanoseconds) to human readable form (eg. 1.05s
). This is useful eg. when using logging or trappers. These functions have their counterpart suitable for use in spy processing code manually implemented in Bean Shell.