text: /**
   * @file LogAttribute.h
   * LogAttribute class declaration
   *
   * 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.
   */
  #ifndef EXTENSIONS_STANDARD_PROCESSORS_PROCESSORS_LOGATTRIBUTE_H_
  #define EXTENSIONS_STANDARD_PROCESSORS_PROCESSORS_LOGATTRIBUTE_H_
  
  #include <memory>
  #include <string>
  #include <utility>
  #include <vector>
  
  #include "FlowFileRecord.h"
  #include "core/Processor.h"
  #include "core/ProcessSession.h"
  #include "core/Core.h"
  #include "core/Resource.h"
  #include "core/logging/LoggerConfiguration.h"
  
  namespace org {
  namespace apache {
  namespace nifi {
  namespace minifi {
  namespace processors {
  
  // LogAttribute Class
  class LogAttribute : public core::Processor {
   public:
    // Constructor
    /*!
     * Create a new processor
     */
    explicit LogAttribute(std::string name, utils::Identifier uuid = utils::Identifier())
        : Processor(std::move(name), uuid),
          flowfiles_to_log_(1),
          hexencode_(false),
          max_line_length_(80U),
          logger_(logging::LoggerFactory<LogAttribute>::getLogger()) {
    }
    // Destructor
    virtual ~LogAttribute() = default;
    // Processor Name
    static constexpr char const* ProcessorName = "LogAttribute";
    // Supported Properties
    static core::Property LogLevel;
    static core::Property AttributesToLog;
    static core::Property AttributesToIgnore;
    static core::Property LogPayload;
    static core::Property HexencodePayload;
    static core::Property MaxPayloadLineLength;
    static core::Property LogPrefix;
    static core::Property FlowFilesToLog;
    // Supported Relationships
    static core::Relationship Success;
    enum LogAttrLevel {
      LogAttrLevelTrace,
      LogAttrLevelDebug,
      LogAttrLevelInfo,
      LogAttrLevelWarn,
      LogAttrLevelError
    };
    // Convert log level from string to enum
    bool logLevelStringToEnum(const std::string &logStr, LogAttrLevel &level) {
      if (logStr == "trace") {
        level = LogAttrLevelTrace;
        return true;
      } else if (logStr == "debug") {
        level = LogAttrLevelDebug;
        return true;
      } else if (logStr == "info") {
        level = LogAttrLevelInfo;
        return true;
      } else if (logStr == "warn") {
        level = LogAttrLevelWarn;
        return true;
      } else if (logStr == "error") {
        level = LogAttrLevelError;
        return true;
      } else {
        return false;
      }
    }
    // Nest Callback Class for read stream
    class ReadCallback : public InputStreamCallback {
     public:
      ReadCallback(std::shared_ptr<logging::Logger> logger, size_t size)
          : logger_(std::move(logger))
          , buffer_(size)  {
      }
      int64_t process(const std::shared_ptr<io::BaseStream>& stream) {
        if (buffer_.size() == 0U) {
          return 0U;
        }
        int ret = stream->read(buffer_.data(), buffer_.size());
        if (ret != buffer_.size()) {
          logger_->log_error("%zu bytes were requested from the stream but %d bytes were read. Rolling back.", buffer_.size(), ret);
          throw Exception(PROCESSOR_EXCEPTION, "Failed to read the entire FlowFile.");
        }
        return buffer_.size();
      }
      std::shared_ptr<logging::Logger> logger_;
      std::vector<uint8_t> buffer_;
    };
  
   public:
    void onSchedule(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::ProcessSessionFactory> &factory) override;
    // OnTrigger method, implemented by NiFi LogAttribute
    void onTrigger(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::ProcessSession> &session) override;
    // Initialize, over write by NiFi LogAttribute
    void initialize(void) override;
  
   private:
    uint64_t flowfiles_to_log_;
    bool hexencode_;
    uint32_t max_line_length_;
    // Logger
    std::shared_ptr<logging::Logger> logger_;
  };
  
  REGISTER_RESOURCE(LogAttribute, "Logs attributes of flow files in the MiNiFi application log.");
  
  }  // namespace processors
  }  // namespace minifi
  }  // namespace nifi
  }  // namespace apache
  }  // namespace org
  
  #endif  // EXTENSIONS_STANDARD_PROCESSORS_PROCESSORS_LOGATTRIBUTE_H_
  