| /** @file |
| |
| Logging |
| |
| @section license License |
| |
| 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. |
| |
| @verbatim |
| int Log::access (LogAccess *entry); |
| |
| The return value is Log::OK if all log objects successfully logged the |
| entry. Otherwise, it has the following bits set to indicate what happened |
| |
| ret_val & Log::SKIP - at least one object filtered the entry |
| - transaction logging has been disabled |
| - the logging system is sampling and it is |
| not yet time for a new sample |
| - no log objects have been defined |
| - entry to log is empty |
| |
| ret_val & Log::FAIL an internal limit of the logging system was |
| exceeded preventing entry from being logged |
| |
| ret_val & Log::FULL the logging space has been exhausted |
| |
| @endverbatim |
| |
| @section example Example usage of the API |
| |
| @code |
| LogAccess entry(this); |
| int ret = Log::access(&entry); |
| @endcode |
| |
| */ |
| |
| #pragma once |
| |
| #include <cstdarg> |
| #include "tscore/ink_platform.h" |
| #include "tscore/EventNotify.h" |
| #include "tscore/Regression.h" |
| #include "records/I_RecProcess.h" |
| #include "LogFile.h" |
| #include "LogBuffer.h" |
| |
| #include <unordered_map> |
| |
| class LogAccess; |
| class LogFieldList; |
| class LogFilterList; |
| class LogFormatList; |
| struct LogBufferHeader; |
| class LogFile; |
| class LogBuffer; |
| class LogFormat; |
| class LogObject; |
| class LogConfig; |
| class TextLogObject; |
| |
| class LogFlushData |
| { |
| public: |
| LINK(LogFlushData, link); |
| Ptr<LogFile> m_logfile; |
| LogBuffer *logbuffer = nullptr; |
| void *m_data; |
| int m_len; |
| |
| LogFlushData(LogFile *logfile, void *data, int len = -1) : m_logfile(logfile), m_data(data), m_len(len) {} |
| ~LogFlushData() |
| { |
| switch (m_logfile->m_file_format) { |
| case LOG_FILE_BINARY: |
| logbuffer = static_cast<LogBuffer *>(m_data); |
| LogBuffer::destroy(logbuffer); |
| break; |
| case LOG_FILE_ASCII: |
| case LOG_FILE_PIPE: |
| free(m_data); |
| break; |
| case N_LOGFILE_TYPES: |
| default: |
| ink_release_assert(!"Unknown file format type!"); |
| } |
| } |
| }; |
| |
| /** |
| This object exists to provide a namespace for the logging system. |
| It contains all data types and global variables relevant to the |
| logging system. You can't actually create a Log object, so all |
| members are static. |
| */ |
| class Log |
| { |
| public: |
| // Prevent creation of any instances of this class. |
| // |
| Log() = delete; |
| |
| enum ReturnCodeFlags { |
| LOG_OK = 1, |
| SKIP = 2, |
| AGGR = 4, |
| FAIL = 8, |
| FULL = 16, |
| }; |
| |
| enum LoggingMode { |
| LOG_MODE_NONE = 0, |
| LOG_MODE_ERRORS, // log *only* errors |
| LOG_MODE_TRANSACTIONS, // log *only* transactions |
| LOG_MODE_FULL |
| }; |
| |
| enum InitFlags { |
| FIELDS_INITIALIZED = 1, |
| FULLY_INITIALIZED = 2, |
| }; |
| |
| enum ConfigFlags { |
| NO_REMOTE_MANAGEMENT = 1, |
| LOGCAT = 4, |
| }; |
| |
| enum RollingEnabledValues { |
| NO_ROLLING = 0, |
| ROLL_ON_TIME_ONLY, |
| ROLL_ON_SIZE_ONLY, |
| ROLL_ON_TIME_OR_SIZE, |
| ROLL_ON_TIME_AND_SIZE, |
| INVALID_ROLLING_VALUE |
| }; |
| |
| enum { |
| MIN_ROLLING_INTERVAL_SEC = 30, // 30 second minimum rolling interval |
| MAX_ROLLING_INTERVAL_SEC = 86400 // 24 hrs rolling interval max |
| }; |
| |
| // main interface |
| static void init(int configFlags = 0); |
| static void init_fields(); |
| |
| static bool |
| transaction_logging_enabled() |
| { |
| return (logging_mode == LOG_MODE_FULL || logging_mode == LOG_MODE_TRANSACTIONS); |
| } |
| |
| static bool |
| error_logging_enabled() |
| { |
| return (logging_mode == LOG_MODE_FULL || logging_mode == LOG_MODE_ERRORS); |
| } |
| |
| static int access(LogAccess *lad); |
| static int va_error(const char *format, va_list ap); |
| static int error(const char *format, ...) TS_PRINTFLIKE(1, 2); |
| |
| // public data members |
| static LogObject *error_log; |
| /** The latest fully initialized LogConfig. |
| * |
| * This is the safe, fully initialed LogConfig object to query against when |
| * performing logging operations. |
| */ |
| static LogConfig *config; |
| static LogFieldList global_field_list; |
| static std::unordered_map<std::string, LogField *> field_symbol_hash; |
| static LoggingMode logging_mode; |
| |
| // logging thread stuff |
| static EventNotify *preproc_notify; |
| static void *preproc_thread_main(void *args); |
| static EventNotify *flush_notify; |
| static InkAtomicList *flush_data_list; |
| static void *flush_thread_main(void *args); |
| |
| static int preproc_threads; |
| |
| // reconfiguration stuff |
| static void change_configuration(); |
| |
| static int handle_logging_mode_change(const char *name, RecDataT data_type, RecData data, void *cookie); |
| static int handle_periodic_tasks_int_change(const char *name, RecDataT data_type, RecData data, void *cookie); |
| |
| /** Check each log file path to see whether it exists and re-open if not. |
| * |
| * This is called when an external log rotation entity has moved log files to |
| * rolled names. This checks whether the original log file exists and, if |
| * not, closes the file descriptor and re-opens the file. |
| */ |
| static int handle_log_rotation_request(); |
| |
| friend void RegressionTest_LogObjectManager_Transfer(RegressionTest *, int, int *); |
| |
| private: |
| static void periodic_tasks(long time_now); |
| static void create_threads(); |
| static void init_when_enabled(); |
| |
| static int init_status; |
| static int config_flags; |
| static bool logging_mode_changed; |
| static bool log_rotate_signal_received; |
| static uint32_t periodic_tasks_interval; |
| }; |
| |
| static inline bool |
| LogThrottlingIsValid(int throttling_val) |
| { |
| return throttling_val >= 0; |
| } |
| |
| static inline bool |
| LogRollingEnabledIsValid(int enabled) |
| { |
| return (enabled >= Log::NO_ROLLING || enabled < Log::INVALID_ROLLING_VALUE); // lgtm[cpp/constant-comparison] |
| } |