Class TailFile
java.lang.Object
org.apache.nifi.components.AbstractConfigurableComponent
org.apache.nifi.processor.AbstractSessionFactoryProcessor
org.apache.nifi.processor.AbstractProcessor
org.apache.nifi.processors.standard.TailFile
- All Implemented Interfaces:
org.apache.nifi.components.ConfigurableComponent,org.apache.nifi.processor.Processor
@TriggerSerially
@InputRequirement(INPUT_FORBIDDEN)
@Tags({"tail","file","log","text","source"})
@CapabilityDescription("\"Tails\" a file, or a list of files, ingesting data from the file as it is written to the file. The file is expected to be textual. Data is ingested only when a new line is encountered (carriage return or new-line character or combination). If the file to tail is periodically \"rolled over\", as is generally the case with log files, an optional Rolling Filename Pattern can be used to retrieve data from files that have rolled over, even if the rollover occurred while NiFi was not running (provided that the data still exists upon restart of NiFi). It is generally advisable to set the Run Schedule to a few seconds, rather than running with the default value of 0 secs, as this Processor will consume a lot of resources if scheduled very aggressively. At this time, this Processor does not support ingesting files that have been compressed when \'rolled over\'.")
@Stateful(scopes={LOCAL,CLUSTER},
description="Stores state about where in the Tailed File it left off so that on restart it does not have to duplicate data. State is stored either local or clustered depend on the <File Location> property.")
@WritesAttribute(attribute="tailfile.original.path",
description="Path of the original file the flow file comes from.")
@Restricted(restrictions=@Restriction(requiredPermission=READ_FILESYSTEM,explanation="Provides operator the ability to read from any file that NiFi has access to."))
@DefaultSchedule(strategy=TIMER_DRIVEN,
period="30 sec")
public class TailFile
extends org.apache.nifi.processor.AbstractProcessor
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static class(package private) static class(package private) static classA simple Java class to hold information about our state so that we can maintain this state across multiple invocations of the Processor -
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.PropertyDescriptorprivate final AtomicBooleanprivate final AtomicLong(package private) static final org.apache.nifi.components.PropertyDescriptorprivate final ByteArrayOutputStreamprivate Pattern(package private) static final org.apache.nifi.components.AllowableValue(package private) static final org.apache.nifi.components.AllowableValue(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final String(package private) static final org.apache.nifi.components.PropertyDescriptorprivate long(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.AllowableValue(package private) static final org.apache.nifi.components.AllowableValueprivate static final byte[](package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.PropertyDescriptorprivate intprivate static final List<org.apache.nifi.components.PropertyDescriptor> (package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.processor.Relationshipprivate static final Set<org.apache.nifi.processor.Relationship> private boolean(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.AllowableValue(package private) static final org.apache.nifi.components.AllowableValue(package private) static final org.apache.nifi.components.AllowableValue(package private) static final org.apache.nifi.components.PropertyDescriptor(package private) static final org.apache.nifi.components.PropertyDescriptorprivate Map<String, TailFile.TailFileObject> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate voidvoidcleanup(org.apache.nifi.processor.ProcessContext context) collectKeysToBeRemoved(Map<String, String> sessionStates) voidcompileRegex(org.apache.nifi.processor.ProcessContext context) private TailFile.TailFileStateconsumeFileFully(File file, org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, TailFile.TailFileObject tfo) Creates a new FlowFile that contains the entire contents of the given file and transfers that FlowFile to success.private FileChannelcreateReader(File file, long position) protected Collection<org.apache.nifi.components.ValidationResult> customValidate(org.apache.nifi.components.ValidationContext context) private voidflushByteArrayOutputStream(ByteArrayOutputStream baos, OutputStream out, Checksum checksum, boolean ignoreRegex) private voidflushLinesBuffer(OutputStream out, Checksum checksum) longgetFilesToTail(String baseDir, String fileRegex, boolean isRecursive, long maxAge) Method to list the files to tail according to the given base directory and using the user-provided regular expressionSet<org.apache.nifi.processor.Relationship> getRolledOffFiles(org.apache.nifi.processor.ProcessContext context, long minTimestamp, String tailFilePath) Returns a list of all Files that match the following criteria: Filename matches the Rolling Filename Pattern Filename does not match the actual file being tailed The Last Modified Time on the file is equal to or later than the given minimum timestamp(package private) Map<String, TailFile.TailFileObject> getState()private org.apache.nifi.components.state.ScopegetStateScope(org.apache.nifi.processor.ProcessContext context) protected List<org.apache.nifi.components.PropertyDescriptor> private voidlookup(org.apache.nifi.processor.ProcessContext context) voidvoidonPropertyModified(org.apache.nifi.components.PropertyDescriptor descriptor, String oldValue, String newValue) voidonTrigger(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session) private voidpersistState(Map<String, String> state, org.apache.nifi.processor.ProcessSession session, org.apache.nifi.processor.ProcessContext context) private voidpersistState(TailFile.TailFileObject tfo, org.apache.nifi.processor.ProcessSession session, org.apache.nifi.processor.ProcessContext context) private voidprocessTailFile(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile) private longreadLines(FileChannel reader, ByteBuffer buffer, OutputStream out, Checksum checksum, Boolean reReadOnNul) private longreadLines(FileChannel reader, ByteBuffer buffer, OutputStream out, Checksum checksum, Boolean reReadOnNul, boolean readFully) Read new lines from the given FileChannel, copying it to the given Output Stream.private booleanrecoverRolledFiles(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile, Long expectedChecksum, long timestamp, long position) Finds any files that have rolled over and have not yet been ingested by this Processor.private booleanrecoverRolledFiles(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile, List<File> rolledOffFiles, Long expectedChecksum, long position) Finds any files that have rolled over and have not yet been ingested by this Processor.private voidprivate voidrecoverState(Map<String, String> stateValues, String filePath) Updates member variables to reflect the "expected recovery checksum" and seek to the appropriate location in the tailed file, updating our checksum, so that we are ready to proceed with theonTrigger(ProcessContext, ProcessSession)call.voidrecoverState(org.apache.nifi.processor.ProcessContext context) private voidresetState(String filePath) private booleantailRolledFile(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile, Long expectedChecksum, long position, TailFile.TailFileObject tfo, File fileToTail, boolean readFully, boolean tailingPostRollover) Methods inherited from class org.apache.nifi.processor.AbstractProcessor
onTriggerMethods inherited from class org.apache.nifi.processor.AbstractSessionFactoryProcessor
getControllerServiceLookup, getIdentifier, getLogger, getNodeTypeProvider, init, initialize, isConfigurationRestored, isScheduled, toString, updateConfiguredRestoredTrue, updateScheduledFalse, updateScheduledTrueMethods inherited from class org.apache.nifi.components.AbstractConfigurableComponent
equals, getPropertyDescriptor, getPropertyDescriptors, getSupportedDynamicPropertyDescriptor, hashCode, validateMethods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface org.apache.nifi.components.ConfigurableComponent
getPropertyDescriptor, getPropertyDescriptors, validateMethods inherited from interface org.apache.nifi.processor.Processor
isStateful, migrateProperties, migrateRelationships
-
Field Details
-
MAP_PREFIX
- See Also:
-
NEW_LINE_BYTES
private static final byte[] NEW_LINE_BYTES -
LOCATION_LOCAL
static final org.apache.nifi.components.AllowableValue LOCATION_LOCAL -
LOCATION_REMOTE
static final org.apache.nifi.components.AllowableValue LOCATION_REMOTE -
MODE_SINGLEFILE
static final org.apache.nifi.components.AllowableValue MODE_SINGLEFILE -
MODE_MULTIFILE
static final org.apache.nifi.components.AllowableValue MODE_MULTIFILE -
START_BEGINNING_OF_TIME
static final org.apache.nifi.components.AllowableValue START_BEGINNING_OF_TIME -
START_CURRENT_FILE
static final org.apache.nifi.components.AllowableValue START_CURRENT_FILE -
START_CURRENT_TIME
static final org.apache.nifi.components.AllowableValue START_CURRENT_TIME -
BASE_DIRECTORY
static final org.apache.nifi.components.PropertyDescriptor BASE_DIRECTORY -
MODE
static final org.apache.nifi.components.PropertyDescriptor MODE -
FILENAME
static final org.apache.nifi.components.PropertyDescriptor FILENAME -
ROLLING_FILENAME_PATTERN
static final org.apache.nifi.components.PropertyDescriptor ROLLING_FILENAME_PATTERN -
POST_ROLLOVER_TAIL_PERIOD
static final org.apache.nifi.components.PropertyDescriptor POST_ROLLOVER_TAIL_PERIOD -
STATE_LOCATION
static final org.apache.nifi.components.PropertyDescriptor STATE_LOCATION -
START_POSITION
static final org.apache.nifi.components.PropertyDescriptor START_POSITION -
RECURSIVE
static final org.apache.nifi.components.PropertyDescriptor RECURSIVE -
LOOKUP_FREQUENCY
static final org.apache.nifi.components.PropertyDescriptor LOOKUP_FREQUENCY -
MAXIMUM_AGE
static final org.apache.nifi.components.PropertyDescriptor MAXIMUM_AGE -
REREAD_ON_NUL
static final org.apache.nifi.components.PropertyDescriptor REREAD_ON_NUL -
LINE_START_PATTERN
static final org.apache.nifi.components.PropertyDescriptor LINE_START_PATTERN -
MAX_BUFFER_LENGTH
static final org.apache.nifi.components.PropertyDescriptor MAX_BUFFER_LENGTH -
PRE_ALLOCATED_BUFFER_SIZE
static final org.apache.nifi.components.PropertyDescriptor PRE_ALLOCATED_BUFFER_SIZE -
PROPERTY_DESCRIPTORS
-
REL_SUCCESS
static final org.apache.nifi.processor.Relationship REL_SUCCESS -
RELATIONSHIPS
-
states
-
lastLookup
-
isMultiChanging
-
requireStateLookup
private volatile boolean requireStateLookup -
linesBuffer
-
lineStartPattern
-
maxBufferBytes
private volatile long maxBufferBytes -
preAllocatedBufferSize
private volatile int preAllocatedBufferSize
-
-
Constructor Details
-
TailFile
public TailFile()
-
-
Method Details
-
getSupportedPropertyDescriptors
- Overrides:
getSupportedPropertyDescriptorsin classorg.apache.nifi.components.AbstractConfigurableComponent
-
getRelationships
- Specified by:
getRelationshipsin interfaceorg.apache.nifi.processor.Processor- Overrides:
getRelationshipsin classorg.apache.nifi.processor.AbstractSessionFactoryProcessor
-
onPropertyModified
public void onPropertyModified(org.apache.nifi.components.PropertyDescriptor descriptor, String oldValue, String newValue) - Specified by:
onPropertyModifiedin interfaceorg.apache.nifi.components.ConfigurableComponent- Overrides:
onPropertyModifiedin classorg.apache.nifi.components.AbstractConfigurableComponent
-
customValidate
protected Collection<org.apache.nifi.components.ValidationResult> customValidate(org.apache.nifi.components.ValidationContext context) - Overrides:
customValidatein classorg.apache.nifi.components.AbstractConfigurableComponent
-
onPrimaryNodeChange
@OnPrimaryNodeStateChange public void onPrimaryNodeChange() -
lookup
-
compileRegex
@OnScheduled public void compileRegex(org.apache.nifi.processor.ProcessContext context) -
recoverState
@OnScheduled public void recoverState(org.apache.nifi.processor.ProcessContext context) throws IOException - Throws:
IOException
-
initStates
-
recoverState
- Throws:
IOException
-
getFilesToTail
private List<String> getFilesToTail(String baseDir, String fileRegex, boolean isRecursive, long maxAge) Method to list the files to tail according to the given base directory and using the user-provided regular expression- Parameters:
baseDir- base directory to recursively look intofileRegex- expression regular used to match files to tailisRecursive- true if looking for file recursively, false otherwise- Returns:
- List of files to tail
-
recoverState
Updates member variables to reflect the "expected recovery checksum" and seek to the appropriate location in the tailed file, updating our checksum, so that we are ready to proceed with theonTrigger(ProcessContext, ProcessSession)call.- Parameters:
stateValues- the values that were recovered from state that was previously stored. This Map should be populated with the keys defined inTailFile.TailFileState.StateKeys.filePath- the file of the file for which state must be recovered- Throws:
IOException- if unable to seek to the appropriate location in the tailed file.
-
resetState
-
cleanup
@OnStopped public void cleanup(org.apache.nifi.processor.ProcessContext context) -
cleanReader
-
onTrigger
public void onTrigger(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session) throws org.apache.nifi.processor.exception.ProcessException - Specified by:
onTriggerin classorg.apache.nifi.processor.AbstractProcessor- Throws:
org.apache.nifi.processor.exception.ProcessException
-
collectKeysToBeRemoved
-
processTailFile
private void processTailFile(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile) -
readLines
private long readLines(FileChannel reader, ByteBuffer buffer, OutputStream out, Checksum checksum, Boolean reReadOnNul) throws IOException - Throws:
IOException
-
readLines
private long readLines(FileChannel reader, ByteBuffer buffer, OutputStream out, Checksum checksum, Boolean reReadOnNul, boolean readFully) throws IOException Read new lines from the given FileChannel, copying it to the given Output Stream. The Checksum is used in order to later determine whether or not data has been consumed.- Parameters:
reader- The FileChannel to read data frombuffer- the buffer to use for copying dataout- the OutputStream to copy the data tochecksum- the Checksum object to use in order to calculate checksum for recovery purposesreReadOnNul- If set to 'true', ASCII NUL characters will be treated as temporary values and a NulCharacterEncounteredException is thrown. This allows the caller to re-attempt a read from the same position. If set to 'false' these characters will be treated as regular content.readFully- If set to 'true' the last chunk of bytes after the last whole line will be also written to the OutputStream- Returns:
- The new position after the lines have been read
- Throws:
IOException- if an I/O error occurs.
-
flushByteArrayOutputStream
private void flushByteArrayOutputStream(ByteArrayOutputStream baos, OutputStream out, Checksum checksum, boolean ignoreRegex) throws IOException - Throws:
IOException
-
flushLinesBuffer
- Throws:
IOException
-
getRolledOffFiles
private List<File> getRolledOffFiles(org.apache.nifi.processor.ProcessContext context, long minTimestamp, String tailFilePath) throws IOException Returns a list of all Files that match the following criteria:- Filename matches the Rolling Filename Pattern
- Filename does not match the actual file being tailed
- The Last Modified Time on the file is equal to or later than the given minimum timestamp
The List that is returned will be ordered by file timestamp, providing the oldest file first.
- Parameters:
context- the ProcessContext to use in order to determine Processor configurationminTimestamp- any file with a Last Modified Time before this timestamp will not be returned- Returns:
- a list of all Files that have rolled over
- Throws:
IOException- if unable to perform the listing of files
-
getStateScope
private org.apache.nifi.components.state.Scope getStateScope(org.apache.nifi.processor.ProcessContext context) -
persistState
private void persistState(TailFile.TailFileObject tfo, org.apache.nifi.processor.ProcessSession session, org.apache.nifi.processor.ProcessContext context) -
persistState
-
createReader
-
getState
Map<String,TailFile.TailFileObject> getState() -
recoverRolledFiles
private boolean recoverRolledFiles(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile, Long expectedChecksum, long timestamp, long position) Finds any files that have rolled over and have not yet been ingested by this Processor. Each of these files that is found will be ingested as its own FlowFile. If a file is found that has been partially ingested, the rest of the file will be ingested as a single FlowFile but the data that already has been ingested will not be ingested again.- Parameters:
context- the ProcessContext to use in order to obtain Processor configuration.session- the ProcessSession to use in order to interact with FlowFile creation and content.expectedChecksum- the checksum value that is expected for the oldest file from offset 0 through <position>.timestamp- the latest Last Modified Timestamp that has been consumed. Any data that was written before this data will not be ingested.position- the byte offset in the file being tailed, where tailing last left off.- Returns:
trueif the file being tailed has rolled over,falseotherwise
-
recoverRolledFiles
private boolean recoverRolledFiles(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile, List<File> rolledOffFiles, Long expectedChecksum, long position) Finds any files that have rolled over and have not yet been ingested by this Processor. Each of these files that is found will be ingested as its own FlowFile. If a file is found that has been partially ingested, the rest of the file will be ingested as a single FlowFile but the data that already has been ingested will not be ingested again.- Parameters:
context- the ProcessContext to use in order to obtain Processor configuration.session- the ProcessSession to use in order to interact with FlowFile creation and content.expectedChecksum- the checksum value that is expected for the oldest file from offset 0 through <position>.position- the byte offset in the file being tailed, where tailing last left off.- Returns:
trueif the file being tailed has rolled over, false otherwise
-
tailRolledFile
private boolean tailRolledFile(org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, String tailFile, Long expectedChecksum, long position, TailFile.TailFileObject tfo, File fileToTail, boolean readFully, boolean tailingPostRollover) throws IOException - Throws:
IOException
-
consumeFileFully
private TailFile.TailFileState consumeFileFully(File file, org.apache.nifi.processor.ProcessContext context, org.apache.nifi.processor.ProcessSession session, TailFile.TailFileObject tfo) throws IOException Creates a new FlowFile that contains the entire contents of the given file and transfers that FlowFile to success. This method will commit the given session and emit an appropriate Provenance Event.- Parameters:
file- the file to ingestcontext- the ProcessContextsession- the ProcessSessiontfo- the current state- Returns:
- the new, updated state that reflects that the given file has been ingested.
- Throws:
IOException
-
getCurrentTimeMs
public long getCurrentTimeMs()
-