[
https://issues.apache.org/jira/browse/NIFI-2341?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15446131#comment-15446131
]
ASF GitHub Bot commented on NIFI-2341:
--------------------------------------
Github user trixpan commented on a diff in the pull request:
https://github.com/apache/nifi/pull/785#discussion_r76623940
--- Diff:
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ParseCEF.java
---
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nifi.processors.standard;
+
+import com.fluenda.parcefone.event.CEFHandlingException;
+import com.fluenda.parcefone.event.CommonEvent;
+import com.fluenda.parcefone.parser.CEFParser;
+
+
+import org.apache.nifi.annotation.behavior.EventDriven;
+import org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
+import org.apache.nifi.annotation.behavior.SideEffectFree;
+import org.apache.nifi.annotation.behavior.SupportsBatching;
+import org.apache.nifi.annotation.behavior.WritesAttribute;
+import org.apache.nifi.annotation.behavior.WritesAttributes;
+import org.apache.nifi.annotation.documentation.CapabilityDescription;
+import org.apache.nifi.annotation.documentation.SeeAlso;
+import org.apache.nifi.annotation.documentation.Tags;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.AbstractProcessor;
+import org.apache.nifi.processor.ProcessContext;
+import org.apache.nifi.processor.ProcessSession;
+import org.apache.nifi.processor.Relationship;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.processor.io.InputStreamCallback;
+import org.apache.nifi.stream.io.StreamUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+@EventDriven
+@SideEffectFree
+@SupportsBatching
+@InputRequirement(Requirement.INPUT_REQUIRED)
+@Tags({"logs", "cef", "attributes", "system", "event", "message"})
+@CapabilityDescription("Parses the contents of a CEF formatted message and
adds attributes to the FlowFile for " +
+ "headers and extensions of the parts of the CEF message.\n" +
+ "Note: This Processor expects CEF messages WITHOUT the syslog
headers (i.e. starting at \"CEF:0\"")
+@WritesAttributes({@WritesAttribute(attribute = "cef.header.version",
description = "The version of the CEF message."),
+ @WritesAttribute(attribute = "cef.header.deviceVendor", description =
"The Device Vendor of the CEF message."),
+ @WritesAttribute(attribute = "cef.header.deviceProduct", description =
"The deviceProduct of the CEF message."),
+ @WritesAttribute(attribute = "cef.header.deviceVersion", description =
"The deviceVersion of the CEF message."),
+ @WritesAttribute(attribute = "cef.header.deviceEventClassId",
description = "The deviceEventClassId of the CEF message."),
+ @WritesAttribute(attribute = "cef.header.name", description = "The
name of the CEF message."),
+ @WritesAttribute(attribute = "cef.header.severity", description = "The
severity of the CEF message."),
+ @WritesAttribute(attribute = "cef.extension.*", description = "The key
and value generated by the parsing of the message.")})
+@SeeAlso({ParseSyslog.class})
+
+public class ParseCEF extends AbstractProcessor {
+
+
+
+ static final Relationship REL_FAILURE = new Relationship.Builder()
+ .name("failure")
+ .description("Any FlowFile that could not be parsed as a CEF
message will be transferred to this Relationship without any attributes being
added")
+ .build();
+ static final Relationship REL_SUCCESS = new Relationship.Builder()
+ .name("success")
+ .description("Any FlowFile that is successfully parsed as a CEF
message will be to this Relationship.")
+ .build();
+
+
+ @Override
+ public Set<Relationship> getRelationships() {
+ final Set<Relationship> relationships = new HashSet<>();
+ relationships.add(REL_FAILURE);
+ relationships.add(REL_SUCCESS);
+ return relationships;
+ }
+
+ @Override
+ public void onTrigger(final ProcessContext context, final
ProcessSession session) throws ProcessException {
+ FlowFile flowFile = session.get();
+ if (flowFile == null) {
+ return;
+ }
+
+ final CEFParser parser = new CEFParser();
+ final byte[] buffer = new byte[(int) flowFile.getSize()];
+ session.read(flowFile, new InputStreamCallback() {
+ @Override
+ public void process(final InputStream in) throws IOException {
+ StreamUtils.fillBuffer(in, buffer);
+ }
+ });
+
+ CommonEvent event = null;
+
+ try {
+ event = parser.parse(buffer, true);
+ } catch (Exception e) {
+ // This should never trigger but adding in here as a fencing
mechanism to
+ // address possible ParCEFone bugs.
+ getLogger().error("Parser returned unexpected Exception {}
while processing {}; routing to failure", new Object[] {e, flowFile});
+ session.transfer(flowFile, REL_FAILURE);
+ }
+
+
+ // ParCEFone returns null every time it cannot parse an
+ // event, so we test
+ if (event==null) {
+ getLogger().error("Failed to parse {} as a CEF message: it
does not conform to the CEF standard; routing to failure", new Object[]
{flowFile});
+ session.transfer(flowFile, REL_FAILURE);
+ return;
+ }
+
+ final Map<String, Object> headerFieldMap;
+ final Map<String, Object> extensionFieldMap;
+ try {
+ headerFieldMap = event.getHeader();
+ extensionFieldMap = event.getExtension(true);
+ } catch (CEFHandlingException e) {
+ getLogger().error("Failed to parse {} as a CEF message due to
{}; routing to failure", new Object[] {flowFile, e});
+ session.transfer(flowFile, REL_FAILURE);
+ return;
+ }
+
+
+ final Map<String, String> attributes = new HashMap<>();
+
+ // Process KVs of the Header field
+ for (Map.Entry<String, Object> entry : headerFieldMap.entrySet()) {
+ attributes.put("cef.header."+entry.getKey(),
prettyResult(entry.getValue()));
+ }
+
+ for (Map.Entry<String, Object> entry :
extensionFieldMap.entrySet()) {
+ attributes.put("cef.extension." + entry.getKey(),
prettyResult(entry.getValue()));
+ }
+
+ flowFile = session.putAllAttributes(flowFile, attributes);
+ session.transfer(flowFile, REL_SUCCESS);
+ }
+
+ private String prettyResult(Object entryValue) {
+
+ if (entryValue instanceof InetAddress ) {
+ return ((InetAddress) entryValue).getHostAddress();
+ } else if (entryValue instanceof Date) {
+ // Not to discuss. THere should be no date format other than
internationally agreed formats...
+ final SimpleDateFormat formatter = new
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ // Discuss this
+ // formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
--- End diff --
Like the idea. Something like giving the user the choice to render the
output with either GMT+10 or UTC, correct?
Just don't tell me local without a timezone... for that the answer would be
over my dead body!!! :skull: 8D
> Create a processor to parse logs formated using CEF
> ---------------------------------------------------
>
> Key: NIFI-2341
> URL: https://issues.apache.org/jira/browse/NIFI-2341
> Project: Apache NiFi
> Issue Type: Improvement
> Reporter: Andre
> Assignee: Andre
>
> As NiFi continue to increase its abilities to complement SIEM, Splunk and ELK
> deployments, a number of users will be looking to parse CEF formatted
> logs[1][2].
> CEF is a format specified by Arcsight (now part of HPE) and is described in
> detail in here:
> https://www.protect724.hpe.com/docs/DOC-1072
> [1]
> http://apache-nifi.1125220.n5.nabble.com/Suggestion-of-processors-td9795.html
> [2]
> https://community.hortonworks.com/questions/43185/which-processor-is-used-to-parse-cef-format-logs.html
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)