Created on 11-05-2016 01:57 AM - edited 08-17-2019 08:31 AM
In this article I show how to very quickly build custom logging against source log files. Adding new custom logging to the flow takes only seconds: each new custom log is copy-pasted from an existing one and 3 configuration properties are changed. The result is a single flow with many diverse custom logs against your system.
Use cases include:
A single customized log is achieved by tailing a log file, splitting the lines of text, extracting lines that match a regex, specifiying a custom log filename for the regex-extracted lines, and appending the lines to that custom log file. The diagram below shows more details, which will be elaborated even more later in the article.
For example, you could extract all lines that are WARN and write them to its own log file, or all lines with a specific java class, or all lines with a specific processor name or id … or particular operation, or user, or something more complex.
The above shows only one custom logging flow. You can building many custom logs against the same source log file (e.g. one for WARN, one for ERROR, one for pid, and another for username … whatever.
You can also build many custom log files against multiple source logs. The diagram below shows multiple customized logs in the same flow.
The above flow will create 4 separate custom log files … all written out by the same ExecuteScript.
Note in the above that:
Because all custom log flows are identical except for 3 configs, it is super-fast to create a new flow. Just:
Technical note: when you paste to the pallete, each processor and connection retains the same name but is assigned a new uuid, thereby guaranteeing a new instance of each.
Because you will likely add many custom log flows to the same flow, and each source log file many split into multiple custom log flows (e.g. Source log file 2 above diagram) your pallete may get a bit busy. Dividing each custom log flow into the same logical processor groups helps manage the palette better. It also makes copy-pasting new flows and deleting other custom log flows easier.
Here is what it will look like.
Now you have your choice of managing entire process groups (copy-paste, delete) or processors inside of them (copy-paste, delete), thus giving you more power to quickly add or remove custom logging to your flow:
import org.apache.commons.io.IOUtils import java.nio.charset.* def flowFile = session.get() if(!flowFile) return filename = customfilename.evaluateAttributeExpressions(flowFile).value f = new File("/Users/gkeys/DEV/staging/${filename}") flowFile = session.write(flowFile, {inputStream, outputStream -> try { f.append(IOUtils.toString(inputStream, StandardCharsets.UTF_8)+'\n') } catch(e) { log.error("Error during processing custom logging: ${filename}", e) } } as StreamCallback) session.transfer(flowFile, REL_SUCCESS)
Note that the jar for org.apache.commons.io.IOUtils is placed in Module Directory as set in ExecuteScript
That's it. You can build custom logging from the basic flow shown in the first diagram, and then quickly add new ones in just a few seconds. Because they are so easy and fast to build, you could easily build them as throwaways used only during the development of a piece of code or a project. On the other hand this is NiFi, a first-class enterprise technology for data in motion. Surely custom logging has a place in your production environments.
The following could easily be modified or extended:
Created on 02-26-2019 04:24 PM
Very helpful article - thank you. I am implementing this approach right now but I need to rotate my custom log file when it reaches # MB. Can anyone show me how to do that in the Groovy code above? The article says it can be done (for the given groovy code, it is easy to build rolling logic to your custom log files) but leaves it at that.
Created on 02-26-2019 04:34 PM
Hi Jim, use the log4j library and there is a configuration to use an appender that defines how the logs rotate. Log4j is pretty standard in the java world
Here is a good tutorial: https://www.journaldev.com/10689/log4j-tutorial