File: //proc/self/root/usr/include/hphp/runtime/server/access-log.h
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ACCESS_LOG_H_
#define incl_HPHP_ACCESS_LOG_H_
#include "hphp/runtime/ext/extension.h"
#include "hphp/runtime/server/transport.h"
#include "hphp/runtime/server/virtual-host.h"
#include "hphp/util/thread-local.h"
#include "hphp/util/logger.h"
#include "hphp/util/lock.h"
#include "hphp/util/cronolog.h"
#include "hphp/util/log-file-flusher.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
struct LogWriter;
enum class LogChannel {CRONOLOG, THREADLOCAL, REGULAR};
struct AccessLogFileData {
AccessLogFileData() {}
AccessLogFileData(const std::string& fil,
const std::string& lnk,
const std::string& fmt,
int mpl);
std::string file;
std::string symLink;
std::string format;
int periodMultiplier;
// Concrete LogWriter factories to be used depending on the handle
using factory_t = std::function<
std::unique_ptr<LogWriter>(const AccessLogFileData&, LogChannel)>;
// Ask a registered factory for a new LogWriter instance
std::unique_ptr<LogWriter> Writer(LogChannel chan) const;
static void registerWriter(const std::string& handle, factory_t factory);
private:
std::string m_logOutputType;
static Mutex m_lock;
static std::unordered_map<std::string, factory_t> m_factories;
};
struct AccessLog {
struct ThreadData {
ThreadData() : log(nullptr) {}
FILE *log;
int64_t startTime;
LogFileFlusher flusher;
};
using GetThreadDataFunc = ThreadData* (*)();
explicit AccessLog(GetThreadDataFunc f) :
m_initialized(false), m_fGetThreadData(f) {}
~AccessLog();
void init(const std::string &defaultFormat,
std::vector<AccessLogFileData> &files,
const std::string &username);
void init(const std::string &defaultFormat,
std::map<std::string, AccessLogFileData> &files,
const std::string &username);
void init(const std::string &format, const std::string &symLink,
const std::string &file, const std::string &username);
void log(Transport *transport, const VirtualHost *vhost);
bool setThreadLog(const char *file);
void clearThreadLog();
void onNewRequest();
void flushAllWriters();
private:
bool m_initialized;
Mutex m_lock;
GetThreadDataFunc m_fGetThreadData;
std::unique_ptr<LogWriter> m_defaultWriter;
std::vector<std::shared_ptr<LogWriter>> m_files;
};
struct LogWriter {
explicit LogWriter(LogChannel chan)
: m_channel(chan)
{}
virtual ~LogWriter() {};
virtual void init(const std::string& username,
AccessLog::GetThreadDataFunc fn) = 0;
virtual void write(Transport* transport, const VirtualHost* vhost) = 0;
virtual void flush() {}
protected:
const LogChannel m_channel;
FILE* m_filelog{nullptr};
std::unique_ptr<Cronolog> m_cronolog;
AccessLog::GetThreadDataFunc m_threadDataFn{nullptr};
LogFileFlusher m_flusher;
protected:
FILE* getOutputFile() const;
void recordWriteAndMaybeDropCaches(FILE* out, int bytes);
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ACCESS_LOG_H_