/** @file

  A brief file description

  @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.
 */

/***************************************************************************
 LogFile.cc


 ***************************************************************************/

#include <vector>
#include <string>
#include <algorithm>

#include "tscore/ink_platform.h"
#include "tscore/SimpleTokenizer.h"
#include "tscore/ink_file.h"

#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libgen.h>

#include "iocore/utils/Machine.h"

#include "tscore/BaseLogFile.h"
#include "proxy/logging/LogField.h"
#include "proxy/logging/LogFilter.h"
#include "proxy/logging/LogFormat.h"
#include "proxy/logging/LogBuffer.h"
#include "proxy/logging/LogFile.h"
#include "proxy/logging/LogObject.h"
#include "proxy/logging/LogUtils.h"
#include "proxy/logging/LogConfig.h"
#include "proxy/logging/Log.h"

namespace
{
DbgCtl dbg_ctl_log_file{"log-file"};
DbgCtl dbg_ctl_log{"log"};

} // end anonymous namespace

/*-------------------------------------------------------------------------
  LogFile::LogFile

  This constructor builds a LogFile object given the path, filename, header,
  and logfile format type.  This is the common way to create a new logfile.
  -------------------------------------------------------------------------*/

LogFile::LogFile(const char *name, const char *header, LogFileFormat format, uint64_t signature, size_t ascii_buffer_size,
                 size_t max_line_size, int pipe_buffer_size, LogEscapeType escape_type)
  : m_file_format(format),
    m_name(ats_strdup(name)),
    m_escape_type(escape_type),
    m_header(ats_strdup(header)),
    m_signature(signature),
    m_max_line_size(max_line_size),
    m_pipe_buffer_size(pipe_buffer_size)
{
  if (m_file_format != LOG_FILE_PIPE) {
    m_log = std::make_unique<BaseLogFile>(name, m_signature);
    // Use Log::config->hostname rather than Machine::instance()->hostname
    // because the former is reloadable.
    m_log->set_hostname(Log::config->hostname);
  } else {
    m_log = nullptr;
  }

  m_fd                = -1;
  m_ascii_buffer_size = (ascii_buffer_size < max_line_size ? max_line_size : ascii_buffer_size);

  Dbg(dbg_ctl_log_file, "exiting LogFile constructor, m_name=%s, this=%p, escape_type=%d", m_name, this, escape_type);
}

/*-------------------------------------------------------------------------
  LogFile::LogFile

  This (copy) constructor builds a LogFile object from another LogFile object.
  -------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------
  LogFile::~LogFile
  -------------------------------------------------------------------------*/

LogFile::~LogFile()
{
  Dbg(dbg_ctl_log_file, "entering LogFile destructor, this=%p", this);

  // close_file() checks whether a file is open before attempting to close, so
  // this is safe to call even if a file had not been opened. Further, calling
  // close_file() here ensures that we do not leak file descriptors.
  close_file();

  ats_free(m_header);
  ats_free(m_name);
  Dbg(dbg_ctl_log_file, "exiting LogFile destructor, this=%p", this);
}

/*-------------------------------------------------------------------------
  LogFile::change_name
  -------------------------------------------------------------------------*/

void
LogFile::change_name(const char *new_name)
{
  ats_free(m_name);
  if (m_log) {
    m_log->change_name(new_name);
  }
  m_name = ats_strdup(new_name);
}

/*-------------------------------------------------------------------------
  LogFile::change_header
  -------------------------------------------------------------------------*/

void
LogFile::change_header(const char *header)
{
  ats_free(m_header);
  m_header = ats_strdup(header);
}

/*-------------------------------------------------------------------------
  LogFile::open

  Open the logfile for append access.  This will create a logfile if the
  file does not already exist.
  -------------------------------------------------------------------------*/

int
LogFile::open_file()
{
  // whatever we want to open should have a name
  ink_assert(m_name != nullptr);

  // is_open() takes into account if we're using BaseLogFile or a naked fd
  if (is_open()) {
    return LOG_FILE_NO_ERROR;
  }

  bool file_exists = LogFile::exists(m_name);

  if (m_file_format == LOG_FILE_PIPE) {
    // setup pipe
    if (mkfifo(m_name, S_IRUSR | S_IWUSR | S_IRGRP) < 0) {
      if (errno != EEXIST) {
        Error("Could not create named pipe %s for logging: %s", m_name, strerror(errno));
        return LOG_FILE_COULD_NOT_CREATE_PIPE;
      }
    } else {
      Dbg(dbg_ctl_log_file, "Created named pipe %s for logging", m_name);
    }

    // now open the pipe
    Dbg(dbg_ctl_log_file, "attempting to open pipe %s", m_name);
    m_fd = ::open(m_name, O_WRONLY | O_NDELAY, 0);
    if (m_fd < 0) {
      Dbg(dbg_ctl_log_file, "no readers for pipe %s", m_name);
      return LOG_FILE_NO_PIPE_READERS;
    }

#ifdef F_GETPIPE_SZ
    // adjust pipe size if necessary
    if (m_pipe_buffer_size) {
      long pipe_size = static_cast<long>(fcntl(m_fd, F_GETPIPE_SZ));
      if (pipe_size == -1) {
        Error("Get pipe size failed for pipe %s: %s", m_name, strerror(errno));
      } else {
        Dbg(dbg_ctl_log_file, "Previous buffer size for pipe %s: %ld", m_name, pipe_size);
      }

      int ret = fcntl(m_fd, F_SETPIPE_SZ, m_pipe_buffer_size);
      if (ret == -1) {
        Error("Set pipe size failed for pipe %s to size %d: %s", m_name, m_pipe_buffer_size, strerror(errno));
      }

      pipe_size = static_cast<long>(fcntl(m_fd, F_GETPIPE_SZ));
      if (pipe_size == -1) {
        Error("Get pipe size after setting it failed for pipe %s: %s", m_name, strerror(errno));
      } else {
        Dbg(dbg_ctl_log_file, "New buffer size for pipe %s: %ld", m_name, pipe_size);
      }
    }
#endif // F_GETPIPE_SZ
  } else {
    if (m_log) {
      int status = m_log->open_file(Log::config->logfile_perm);
      if (status == BaseLogFile::LOG_FILE_COULD_NOT_OPEN_FILE) {
        return LOG_FILE_COULD_NOT_OPEN_FILE;
      }
    } else {
      return LOG_FILE_COULD_NOT_OPEN_FILE;
    }
  }

  //
  // If we've opened the file and it didn't already exist, then this is a
  // "new" file and we need to make some initializations.  This is the
  // time to write any headers and do any one-time initialization of the
  // file.
  //
  if (!file_exists) {
    if (m_file_format != LOG_FILE_BINARY && m_header && m_log) {
      Dbg(dbg_ctl_log_file, "writing header to LogFile %s", m_name);
      writeln(m_header, strlen(m_header), fileno(m_log->m_fp), m_name);
    }
  }

  Metrics::Gauge::increment(log_rsb.log_files_open);

  Dbg(dbg_ctl_log, "exiting LogFile::open_file(), file=%s presumably open", m_name);
  return LOG_FILE_NO_ERROR;
}

/*-------------------------------------------------------------------------
  LogFile::close

  Close the current logfile.
  -------------------------------------------------------------------------*/

void
LogFile::close_file()
{
  if (is_open()) {
    if (m_file_format == LOG_FILE_PIPE) {
      if (::close(m_fd)) {
        Error("Error closing LogFile %s: %s.", m_name, strerror(errno));
      } else {
        Dbg(dbg_ctl_log_file, "LogFile %s (fd=%d) is closed", m_name, m_fd);
        Metrics::Gauge::decrement(log_rsb.log_files_open);
      }
      m_fd = -1;
    } else if (m_log) {
      if (m_log->close_file()) {
        Error("Error closing LogFile %s: %s.", m_log->get_name(), strerror(errno));
      } else {
        Dbg(dbg_ctl_log_file, "LogFile %s is closed", m_log->get_name());
        Metrics::Gauge::decrement(log_rsb.log_files_open);
      }
    } else {
      Warning("LogFile %s is open but was not closed", m_name);
    }
  }
}

struct RolledFile {
  RolledFile(const std::string &name, time_t mtime) : _name(name), _mtime(mtime) {}
  std::string _name;
  time_t      _mtime;
};

/**
 * @brief trim rolled files to max number of rolled files, older first
 *
 * @param rolling_max_count - limit to which rolled files will be trimmed
 * @return true if success, false if failure
 */
bool
LogFile::trim_rolled(size_t rolling_max_count)
{
  // man: "dirname() may modify the contents of path, so it may be desirable to pass a copy when calling one of these functions."
  char       *name = ats_strdup(m_name);
  std::string logfile_dir(::dirname((name)));
  ats_free(name);

  // Open the directory
  int dirfd = open(logfile_dir.c_str(), O_RDONLY);
  if (dirfd < 0) {
    Error("Error opening logging directory %s to collect trim candidates: %s", logfile_dir.c_str(), strerror(errno));
    return false;
  }

  // Check logging directory access
  int err;
  do {
    err = faccessat(dirfd, logfile_dir.c_str(), R_OK | W_OK | X_OK, 0);
  } while ((err < 0) && (errno == EINTR));

  if (err < 0) {
    close(dirfd);
    Error("Error accessing logging directory %s: %s", logfile_dir.c_str(), strerror(errno));
    return false;
  }

  // Open the logging directory
  DIR *ld = fdopendir(dirfd);
  if (ld == nullptr) {
    close(dirfd);
    Error("Error opening logging directory %s to collect trim candidates: %s", logfile_dir.c_str(), strerror(errno));
    return false;
  }

  // Collect the rolled file names from the logging directory that match the specified log file name
  std::vector<RolledFile> rolled;
  char                    path[MAXPATHLEN];
  struct dirent          *entry;
  while ((entry = readdir(ld))) {
    struct stat sbuf;
    snprintf(path, MAXPATHLEN, "%s/%s", logfile_dir.c_str(), entry->d_name);
    int sret = ::stat(path, &sbuf);
    if (sret != -1 && S_ISREG(sbuf.st_mode)) {
      int name_len = strlen(m_name);
      int path_len = strlen(path);
      if (path_len > name_len && 0 == ::strncmp(m_name, path, name_len) && LogFile::rolled_logfile(entry->d_name)) {
        rolled.push_back(RolledFile(path, sbuf.st_mtime));
      }
    }
  }

  closedir(ld);

  bool result = true;
  std::sort(rolled.begin(), rolled.end(), [](const RolledFile &a, const RolledFile &b) { return a._mtime > b._mtime; });
  if (rolling_max_count < rolled.size()) {
    for (auto it = rolled.begin() + rolling_max_count; it != rolled.end(); it++) {
      const RolledFile &file = *it;
      if (unlink(file._name.c_str()) < 0) {
        Error("unable to auto-delete rolled logfile %s: %s", file._name.c_str(), strerror(errno));
        result = false;
      } else {
        Dbg(dbg_ctl_log_file, "rolled logfile, %s, was auto-deleted", file._name.c_str());
      }
    }
  }

  rolled.clear();
  return result;
}

/*-------------------------------------------------------------------------
 * LogFile::roll
 * This function is called by a LogObject to roll its files.
 *
 * Return 1 if file rolled, 0 otherwise
-------------------------------------------------------------------------*/
int
LogFile::roll(long interval_start, long interval_end, bool reopen_after_rolling)
{
  if (m_log) {
    // Due to commit 346b419 the BaseLogFile::close_file() is no longer called within BaseLogFile::roll().
    // For diagnostic log files, the rolling is implemented by renaming and destroying the BaseLogFile object
    // and then creating a new BaseLogFile object with the original filename. Due to possible race conditions
    // the old/new object swap happens within lock/unlock calls within Diags.cc.
    // For logging log files, the rolling is implemented by renaming the original file and closing it.
    // Afterwards, the LogFile object will re-open a new file with the original file name using the original object.
    // There is no need to protect against contention since the open/close/writes are all executed under a
    // single log flush thread.
    // Since these two methods of using BaseLogFile are not compatible, we perform the logging log file specific
    // close file operation here within the containing LogFile object.
    if (m_log->roll(interval_start, interval_end)) {
      if (m_log->close_file()) {
        Error("Error closing LogFile %s: %s.", m_log->get_name(), strerror(errno));
      }

      if (reopen_after_rolling) {
        /* If we re-open now log file will be created even if there is nothing being logged */
        m_log->open_file();
      }

      return 1;
    }
  }

  return 0;
}

/*-------------------------------------------------------------------------
  LogFile::reopen_if_moved

  Check whether the file at the log's filename exists and, if not, close
  the current file descriptor and reopen it. This function can be used to
  facilitate external log rotation mechanisms which will move the original
  file to a rolled filename. Logging will happen to that same file
  descriptor until this function is called, at which point the non-existent
  original file will be detected, the file descriptor will be closed, and
  the log file will be re-opened.

  Returns True if the file was re-opened, false otherwise.
  -------------------------------------------------------------------------*/
bool
LogFile::reopen_if_moved()
{
  if (!m_name) {
    return false;
  }
  if (LogFile::exists(m_name)) {
    return false;
  }

  // Both of the following log if there are problems.
  close_file();
  open_file();
  return true;
}

/*-------------------------------------------------------------------------
  LogFile::preproc_and_try_delete

  preprocess the given buffer data before write to target file
  and try to delete it when its reference become zero.
  -------------------------------------------------------------------------*/
int
LogFile::preproc_and_try_delete(LogBuffer *lb)
{
  int              ret = -1;
  LogBufferHeader *buffer_header;

  if (lb == nullptr) {
    Note("Cannot write LogBuffer to LogFile %s; LogBuffer is NULL", m_name);
    return -1;
  }

  ink_atomic_increment(&lb->m_references, 1);

  if ((buffer_header = lb->header()) == nullptr) {
    Note("Cannot write LogBuffer to LogFile %s; LogBufferHeader is NULL", m_name);
    goto done;
  }
  if (buffer_header->entry_count == 0) {
    // no bytes to write
    Note("LogBuffer with 0 entries for LogFile %s, nothing to write", m_name);
    goto done;
  }

  //
  // If the start time for this file has yet to be established, then grab
  // the low_timestamp from the given LogBuffer.  Then, we always set the
  // end time to the high_timestamp, so it's always up to date.
  //
  if (m_log) {
    if (!m_log->m_start_time) {
      m_log->m_start_time = buffer_header->low_timestamp;
    }
    m_log->m_end_time = buffer_header->high_timestamp;
  }

  if (m_file_format == LOG_FILE_BINARY) {
    //
    // Ok, now we need to write the binary buffer to the file, and we
    // can do so in one swift write.  The question is, do we write the
    // LogBufferHeader with each buffer or not?  The answer is yes.
    // Even though we'll be putting down redundant data (things that
    // don't change between buffers), it's not worth trying to separate
    // out the buffer-dependent data from the buffer-independent data.
    //
    LogFlushData *flush_data = new LogFlushData(this, lb);

    Metrics::Counter::increment(log_rsb.num_flush_to_disk, lb->header()->entry_count);
    Metrics::Counter::increment(log_rsb.bytes_flush_to_disk, lb->header()->byte_count);

    ink_atomiclist_push(Log::flush_data_list, flush_data);

    Log::flush_notify->signal();

    //
    // LogBuffer will be deleted in flush thread
    //
    return 0;
  } else if (m_file_format == LOG_FILE_ASCII || m_file_format == LOG_FILE_PIPE) {
    write_ascii_logbuffer3(buffer_header);
    ret = 0;
  } else {
    Note("Cannot write LogBuffer to LogFile %s; invalid file format: %d", m_name, m_file_format);
  }

done:
  LogBuffer::destroy(lb);
  return ret;
}

/*-------------------------------------------------------------------------
  LogFile::write_ascii_logbuffer

  This routine takes the given LogBuffer and writes it (in ASCII) to the
  given file descriptor.  Written as a stand-alone function, it can be
  called from either the local LogBuffer::write routine from inside of the
  proxy, or from an external program (since it is a static function).  The
  return value is the number of bytes written.
  -------------------------------------------------------------------------*/

int
LogFile::write_ascii_logbuffer(LogBufferHeader *buffer_header, int fd, const char *path, const char *alt_format)
{
  ink_assert(buffer_header != nullptr);
  ink_assert(fd >= 0);

  char              fmt_buf[LOG_MAX_FORMATTED_BUFFER];
  char              fmt_line[LOG_MAX_FORMATTED_LINE];
  LogBufferIterator iter(buffer_header);
  LogEntryHeader   *entry_header;
  int               fmt_buf_bytes  = 0;
  int               fmt_line_bytes = 0;
  int               bytes          = 0;

  LogFormatType format_type;
  char         *fieldlist_str;
  char         *printf_str;

  // v3 is identical to v2 for ASCII output: it still uses fmt_fieldlist and
  // fmt_printf; the extra field-type schema is additive and ignored here.
  if (log_segment_version_supported(buffer_header->version)) {
    format_type   = static_cast<LogFormatType>(buffer_header->format_type);
    fieldlist_str = buffer_header->fmt_fieldlist();
    printf_str    = buffer_header->fmt_printf();
  } else {
    Note("Invalid LogBuffer version %d in write_ascii_logbuffer; "
         "supported versions are %d-%d",
         buffer_header->version, LOG_SEGMENT_VERSION_MIN_SUPPORTED, LOG_SEGMENT_VERSION);
    return 0;
  }

  while ((entry_header = iter.next())) {
    fmt_line_bytes = LogBuffer::to_ascii(entry_header, format_type, &fmt_line[0], LOG_MAX_FORMATTED_LINE, fieldlist_str, printf_str,
                                         buffer_header->version, alt_format);
    ink_assert(fmt_line_bytes > 0);

    if (fmt_line_bytes > 0) {
      if ((fmt_line_bytes + fmt_buf_bytes) >= LOG_MAX_FORMATTED_BUFFER) {
        if (!Log::config->logging_space_exhausted) {
          bytes += writeln(fmt_buf, fmt_buf_bytes, fd, path);
        }
        fmt_buf_bytes = 0;
      }
      ink_assert(fmt_buf_bytes < LOG_MAX_FORMATTED_BUFFER);
      ink_assert(fmt_line_bytes < LOG_MAX_FORMATTED_BUFFER - fmt_buf_bytes);
      memcpy(&fmt_buf[fmt_buf_bytes], fmt_line, fmt_line_bytes);
      fmt_buf_bytes += fmt_line_bytes;
      ink_assert(fmt_buf_bytes < LOG_MAX_FORMATTED_BUFFER);
      fmt_buf[fmt_buf_bytes]  = '\n'; // keep entries separate
      fmt_buf_bytes          += 1;
    }
  }
  if (fmt_buf_bytes > 0) {
    if (!Log::config->logging_space_exhausted) {
      ink_assert(fmt_buf_bytes < LOG_MAX_FORMATTED_BUFFER);
      bytes += writeln(fmt_buf, fmt_buf_bytes, fd, path);
    }
  }

  return bytes;
}

int
LogFile::write_ascii_logbuffer3(LogBufferHeader *buffer_header, const char *alt_format)
{
  Dbg(dbg_ctl_log_file,
      "entering LogFile::write_ascii_logbuffer3 for %s "
      "(this=%p)",
      m_name, this);
  ink_assert(buffer_header != nullptr);

  LogBufferIterator iter(buffer_header);
  LogEntryHeader   *entry_header;
  int               fmt_entry_count = 0;
  int               fmt_buf_bytes   = 0;
  int               total_bytes     = 0;

  LogFormatType format_type;
  char         *fieldlist_str;
  char         *printf_str;
  char         *ascii_buffer;

  // Same v2/v3 handling as write_ascii_logbuffer: the v3 schema is additive
  // and not needed for ASCII output.
  if (log_segment_version_supported(buffer_header->version)) {
    format_type   = static_cast<LogFormatType>(buffer_header->format_type);
    fieldlist_str = buffer_header->fmt_fieldlist();
    printf_str    = buffer_header->fmt_printf();
  } else {
    Note("Invalid LogBuffer version %d in write_ascii_logbuffer; "
         "supported versions are %d-%d",
         buffer_header->version, LOG_SEGMENT_VERSION_MIN_SUPPORTED, LOG_SEGMENT_VERSION);
    return 0;
  }

  while ((entry_header = iter.next())) {
    fmt_entry_count = 0;
    fmt_buf_bytes   = 0;

    if (m_file_format == LOG_FILE_PIPE) {
      ascii_buffer = static_cast<char *>(ats_malloc(m_max_line_size));
    } else {
      ascii_buffer = static_cast<char *>(ats_malloc(m_ascii_buffer_size));
    }

    // fill the buffer with as many records as possible
    //
    do {
      if (entry_header->entry_len >= m_max_line_size) {
        Warning("Log is too long(%" PRIu32 "), it would be truncated. max_len:%zu", entry_header->entry_len, m_max_line_size);
      }

      int bytes = LogBuffer::to_ascii(entry_header, format_type, &ascii_buffer[fmt_buf_bytes], m_max_line_size - 1, fieldlist_str,
                                      printf_str, buffer_header->version, alt_format, get_escape_type());

      if (bytes > 0) {
        fmt_buf_bytes               += bytes;
        ascii_buffer[fmt_buf_bytes]  = '\n';
        ++fmt_buf_bytes;
        ++fmt_entry_count;
      } else {
        Note("Failed to convert LogBuffer to ascii, have dropped (%" PRIu32 ") bytes.", entry_header->entry_len);

        Metrics::Counter::increment(log_rsb.num_lost_before_flush_to_disk, fmt_entry_count);
        Metrics::Counter::increment(log_rsb.bytes_lost_before_flush_to_disk, fmt_buf_bytes);
      }
      // if writing to a pipe, fill the buffer with a single
      // record to avoid as much as possible overflowing the
      // pipe buffer
      //
      if (m_file_format == LOG_FILE_PIPE) {
        break;
      }

      if (m_ascii_buffer_size - fmt_buf_bytes < m_max_line_size) {
        break;
      }
    } while ((entry_header = iter.next()));

    // send the buffer to flush thread
    //
    LogFlushData *flush_data = new LogFlushData(this, ascii_buffer, fmt_buf_bytes);

    Metrics::Counter::increment(log_rsb.num_flush_to_disk, fmt_entry_count);
    Metrics::Counter::increment(log_rsb.bytes_flush_to_disk, fmt_buf_bytes);

    ink_atomiclist_push(Log::flush_data_list, flush_data);

    Log::flush_notify->signal();

    total_bytes += fmt_buf_bytes;
  }

  return total_bytes;
}

bool
LogFile::rolled_logfile(char *file)
{
  return BaseLogFile::rolled_logfile(file);
}

bool
LogFile::exists(const char *pathname)
{
  return BaseLogFile::exists(pathname);
}

/*-------------------------------------------------------------------------
  LogFile::writeln

  This function will make sure the following data is written to the
  output file (m_fd) with a trailing newline.
  -------------------------------------------------------------------------*/

int
LogFile::writeln(char *data, int len, int fd, const char *path)
{
  int total_bytes = 0;

  if (len > 0 && data && fd >= 0) {
    struct iovec wvec[2];
    memset(&wvec, 0, sizeof(iovec));
    memset(&wvec[1], 0, sizeof(iovec));
    int bytes_this_write, vcnt = 1;

    wvec[0].iov_base = (void *)data;
    wvec[0].iov_len  = static_cast<size_t>(len);

    if (data[len - 1] != '\n') {
      wvec[1].iov_base = (void *)"\n";
      wvec[1].iov_len  = static_cast<size_t>(1);
      vcnt++;
    }

    if ((bytes_this_write = static_cast<int>(::writev(fd, (const struct iovec *)wvec, vcnt))) < 0) {
      SiteThrottledWarning("An error was encountered in writing to %s: %s.", ((path) ? path : "logfile"), strerror(errno));
    } else {
      total_bytes = bytes_this_write;
    }
  }
  return total_bytes;
}

/*-------------------------------------------------------------------------
  LogFile::check_fd

  This routine will occasionally stat the current logfile to make sure that
  it really does exist. We use fstat() on the open file descriptor to check
  if the file has been unlinked.

  Failure to open the logfile will generate a manager alarm and a Warning.
  -------------------------------------------------------------------------*/

void
LogFile::check_fd()
{
  static bool     failure_last_call = false;
  static unsigned stat_check_count  = 1;

  if ((stat_check_count % Log::config->file_stat_frequency) == 0) {
    //
    // Check if the file still exists using fstat() on the open file descriptor.
    // For regular files that have been unlinked (e.g., by log rotation tools),
    // st_nlink will be 0. Non-regular files like stderr/stdout will never have
    // st_nlink == 0, so this approach works safely for all file types.
    //
    if (m_name && is_open()) {
      int fd = get_fd();
      if (fd >= 0) {
        struct stat st;
        if (fstat(fd, &st) == 0) {
          // If the file has been unlinked, st_nlink will be 0
          // This only happens for regular files, not special files like stderr/stdout
          if (st.st_nlink == 0) {
            close_file();
          }
        } else {
          // fstat failed, the file descriptor may be invalid
          // Fall back to path-based existence check
          if (!LogFile::exists(m_name)) {
            close_file();
          }
        }
      } else {
        // No valid fd, fall back to path-based check
        if (!LogFile::exists(m_name)) {
          close_file();
        }
      }
    }
    stat_check_count = 0;
  }
  stat_check_count++;

  int err = open_file();
  // XXX if open_file() returns, LOG_FILE_FILESYSTEM_CHECKS_FAILED, raise a more informative alarm ...
  if (err != LOG_FILE_NO_ERROR && err != LOG_FILE_NO_PIPE_READERS) {
    if (!failure_last_call) {
      Warning("Traffic Server could not open logfile %s: %s.", m_name, strerror(errno));
    }
    failure_last_call = true;
    return;
  }

  failure_last_call = false;
}

void
LogFile::display(FILE *fd)
{
  fprintf(fd, "Logfile: %s, %s\n", get_name(), (is_open()) ? "file is open" : "file is not open");
}

bool
LogFile::is_open()
{
  if (m_file_format == LOG_FILE_PIPE) {
    return m_fd >= 0;
  } else {
    return m_log && m_log->is_open();
  }
}

/*
 * Returns the fd of the entity (pipe or regular file ) that this object is
 * representing
 *
 * Returns -1 on error, the correct fd otherwise
 */
int
LogFile::get_fd()
{
  if (m_file_format == LOG_FILE_PIPE) {
    return m_fd;
  } else if (m_log && m_log->m_fp) {
    return fileno(m_log->m_fp);
  } else {
    return -1;
  }
}
