Processing and filtering arguments

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.