| /** @file | |
| Base class for log files | |
| @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. | |
| */ | |
| #pragma once | |
| #include <cstdarg> | |
| #include <cstdio> | |
| #include <sys/time.h> | |
| #include <cstdint> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <fcntl.h> | |
| #include "tscore/ink_memory.h" | |
| #include "tscore/ink_string.h" | |
| #include "tscore/ink_file.h" | |
| #include "tscore/ink_cap.h" | |
| #include "tscore/ink_time.h" | |
| #include "tscore/SimpleTokenizer.h" | |
| #define LOGFILE_ROLLED_EXTENSION ".old" | |
| #define LOGFILE_SEPARATOR_STRING "_" | |
| #define LOGFILE_DEFAULT_PERMS (0644) | |
| #define LOGFILE_ROLL_MAXPATHLEN 4096 | |
| #define BASELOGFILE_DEBUG_MODE \ | |
| 0 // change this to 1 to enable debug messages | |
| // TODO find a way to enable this from autotools | |
| enum LogLogPriorityLevel { | |
| LL_Debug = 0, // process does not die | |
| LL_Note, // process does not die | |
| LL_Warning, // process does not die | |
| LL_Error, // process does not die | |
| LL_Fatal, // causes process termination | |
| }; | |
| #define log_log_trace(...) \ | |
| do { \ | |
| if (BASELOGFILE_DEBUG_MODE) \ | |
| BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \ | |
| } while (0) | |
| #define log_log_error(...) \ | |
| do { \ | |
| if (BASELOGFILE_DEBUG_MODE) \ | |
| BaseLogFile::log_log(LL_Error, __VA_ARGS__); \ | |
| } while (0) | |
| /* | |
| * | |
| * BaseMetaInfo class | |
| * | |
| * Used to store persistent information between ATS instances | |
| * | |
| */ | |
| class BaseMetaInfo | |
| { | |
| public: | |
| enum { | |
| DATA_FROM_METAFILE = 1, // metadata was read (or attempted to) | |
| // from metafile | |
| VALID_CREATION_TIME = 2, // creation time is valid | |
| VALID_SIGNATURE = 4, // signature is valid | |
| // (i.e., creation time only) | |
| FILE_OPEN_SUCCESSFUL = 8 // metafile was opened successfully | |
| }; | |
| enum { | |
| BUF_SIZE = 640 // size of read/write buffer | |
| }; | |
| private: | |
| char *_filename{nullptr}; // the name of the meta file | |
| time_t _creation_time{0}; // file creation time | |
| uint64_t _log_object_signature{0}; // log object signature | |
| int _flags{0}; // metainfo status flags | |
| char _buffer[BUF_SIZE]; // read/write buffer | |
| void _read_from_file(); | |
| void _write_to_file(); | |
| void _build_name(const char *filename); | |
| public: | |
| BaseMetaInfo(const char *filename) | |
| { | |
| _build_name(filename); | |
| _read_from_file(); | |
| } | |
| BaseMetaInfo(char *filename, time_t creation) : _creation_time(creation), _log_object_signature(0), _flags(VALID_CREATION_TIME) | |
| { | |
| _build_name(filename); | |
| _write_to_file(); | |
| } | |
| BaseMetaInfo(char *filename, time_t creation, uint64_t signature) | |
| : _creation_time(creation), _log_object_signature(signature), _flags(VALID_CREATION_TIME | VALID_SIGNATURE) | |
| { | |
| _build_name(filename); | |
| _write_to_file(); | |
| } | |
| ~BaseMetaInfo() { ats_free(_filename); } | |
| bool | |
| get_creation_time(time_t *time) | |
| { | |
| if (_flags & VALID_CREATION_TIME) { | |
| *time = _creation_time; | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| bool | |
| get_log_object_signature(uint64_t *signature) | |
| { | |
| if (_flags & VALID_SIGNATURE) { | |
| *signature = _log_object_signature; | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| bool | |
| data_from_metafile() const | |
| { | |
| return (_flags & DATA_FROM_METAFILE ? true : false); | |
| } | |
| bool | |
| file_open_successful() | |
| { | |
| return (_flags & FILE_OPEN_SUCCESSFUL ? true : false); | |
| } | |
| }; | |
| /* | |
| * | |
| * BaseLogFile Class | |
| * | |
| */ | |
| class BaseLogFile | |
| { | |
| public: | |
| // member functions | |
| BaseLogFile() = delete; | |
| BaseLogFile &operator=(const BaseLogFile &) = delete; | |
| BaseLogFile(const char *name); | |
| BaseLogFile(const char *name, uint64_t sig); | |
| BaseLogFile(const BaseLogFile &); | |
| ~BaseLogFile(); | |
| int roll(); | |
| int roll(long interval_start, long interval_end); | |
| static bool rolled_logfile(char *path); | |
| static bool exists(const char *pathname); | |
| int open_file(int perm = -1); | |
| int close_file(); | |
| void change_name(const char *new_name); | |
| void display(FILE *fd = stdout); | |
| const char * | |
| get_name() const | |
| { | |
| return m_name; | |
| } | |
| bool | |
| is_open() | |
| { | |
| return (m_fp != nullptr); | |
| } | |
| off_t | |
| get_size_bytes() const | |
| { | |
| return m_bytes_written; | |
| } | |
| bool | |
| is_init() | |
| { | |
| return m_is_init; | |
| } | |
| const char * | |
| get_hostname() const | |
| { | |
| return m_hostname; | |
| } | |
| void | |
| set_hostname(const char *hn) | |
| { | |
| m_hostname = ats_strdup(hn); | |
| } | |
| static void log_log(LogLogPriorityLevel priority, const char *format, ...); | |
| // member variables | |
| enum { | |
| LOG_FILE_NO_ERROR = 0, | |
| LOG_FILE_COULD_NOT_OPEN_FILE, | |
| }; | |
| FILE *m_fp = nullptr; | |
| long m_start_time = time(nullptr); | |
| long m_end_time = 0L; | |
| uint64_t m_bytes_written = 0; | |
| private: | |
| // member functions | |
| int timestamp_to_str(long timestamp, char *buf, int size); | |
| // member variables | |
| ats_scoped_str m_name; | |
| ats_scoped_str m_hostname; | |
| bool m_is_regfile = false; | |
| bool m_is_init = false; | |
| std::unique_ptr<BaseMetaInfo> m_meta_info = nullptr; | |
| uint64_t m_signature = 0; | |
| bool m_has_signature = false; | |
| }; |