GELF remote logging to graylog
This commit is contained in:
@@ -62,6 +62,7 @@ PHP_METHOD(WrenchBoard, __construct)
|
||||
SET_ENV( "HTTP_X_FORWARDED_FOR" );
|
||||
}
|
||||
zend_string_release(_server);
|
||||
intern->wrenchboard->logMessage("Constructor finished");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ logger:
|
||||
host = "10.0.0.112";
|
||||
port = 12201L;
|
||||
file = 0L;
|
||||
level = "DEBUG"; # 3L;
|
||||
level = "FLOG_MAX";
|
||||
# 0 - ERROR
|
||||
# 1 - WARNING
|
||||
# 2 - INFO
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
#include "clog.h"
|
||||
#include "cfg.h"
|
||||
#include "php_wrenchboard_log.h"
|
||||
|
||||
#include <gelfcpp/output/GelfUDPOutput.hpp>
|
||||
|
||||
#include <gelfcpp/decorator/StaticDecoratorSet.hpp>
|
||||
#include <gelfcpp/decorator/Timestamp.hpp>
|
||||
#include <gelfcpp/decorator/Host.hpp>
|
||||
|
||||
using namespace gelfcpp::output;
|
||||
|
||||
TLogLevel global_log_level = FLOG_MAX; // By default log everything
|
||||
|
||||
GelfUDPOutput graylog(CfgReadChar("logger.host"), CfgReadLong("logger.port"));
|
||||
GelfUDPOutput *graylog;
|
||||
using Decorator = gelfcpp::decorator::StaticDecoratorSet<gelfcpp::decorator::CurrentTimestamp, gelfcpp::decorator::Host>;
|
||||
Decorator decorator;
|
||||
|
||||
void logfmt( TLogLevel level, const char * format, ... ) {
|
||||
if (level > global_log_level) {
|
||||
@@ -36,24 +43,13 @@ void logfmt( TLogLevel level, const char * format, ... ) {
|
||||
va_end (args);
|
||||
// Graylog
|
||||
if (strlen(buffer) > 0) {
|
||||
if (false) {
|
||||
FILE_LOG(logERROR) << "graylog is null!" ;
|
||||
if (graylog) {
|
||||
GELF_MESSAGE(*graylog)(decorator)
|
||||
(buffer)
|
||||
("pid", getpid())
|
||||
("loglevel", FILELog::ToString(level).c_str());
|
||||
} else {
|
||||
gelfcpp::GelfMessageStream stream(graylog);
|
||||
if (stream) {
|
||||
stream.Send(graylog) = gelfcpp::GelfMessageBuilder()
|
||||
(CurrentTimeStamp())
|
||||
("level", FILELog::ToString(level).c_str())
|
||||
("pid", getpid())
|
||||
(buffer);
|
||||
} else {
|
||||
FILE_LOG(logERROR) << "GelfMessageStream failed!" ;
|
||||
}
|
||||
GELF_MESSAGE(graylog)
|
||||
(CurrentTimeStamp())
|
||||
("level", FILELog::ToString(level).c_str())
|
||||
("pid", getpid())
|
||||
(buffer);
|
||||
FILE_LOG(logERROR) << "graylog is null!" ;
|
||||
}
|
||||
} else {
|
||||
FILE_LOG(logERROR) << "buffer length is " << strlen(buffer) ;
|
||||
@@ -79,45 +75,39 @@ void logfmt( TLogLevel level, const char * format, ... ) {
|
||||
}
|
||||
*/
|
||||
|
||||
void GraylogStream(std::string raw) {
|
||||
/*
|
||||
void GraylogStream(TLogLevel level, std::string raw) {
|
||||
if (!graylog) {
|
||||
std::cerr << "graylog is null!"; // We cannot use log here as it will go recursive
|
||||
return; // Not initialized, yet?
|
||||
}
|
||||
if (!raw.empty()) {
|
||||
GELF_MESSAGE(graylog)
|
||||
(CurrentTimeStamp())
|
||||
/* GELF_MESSAGE(*graylog)(decorator)
|
||||
(raw.c_str());
|
||||
("pid", getpid())
|
||||
("level", "FLOG_MAX")
|
||||
(raw.c_str());
|
||||
("loglevel", "FLOG_MAX"); */
|
||||
|
||||
std::string marker ("]: ");
|
||||
|
||||
std::size_t found = raw.find(marker);
|
||||
if (found != std::string::npos) {
|
||||
std::string msg = raw.substr (found + 3);
|
||||
std::string levelString = FILELog::ToString(level);
|
||||
|
||||
if (!msg.empty()) {
|
||||
GELF_MESSAGE(*graylog)(decorator)
|
||||
(msg.c_str())
|
||||
("pid", getpid())
|
||||
("loglevel", levelString.c_str());
|
||||
} else {
|
||||
std::cerr << "Message is empty!";
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Marker '" << marker << "' was not found!";
|
||||
}
|
||||
// */
|
||||
} else {
|
||||
std::cerr << "Raw message is empty!";
|
||||
}
|
||||
*/
|
||||
std::string marker1 ("]: ");
|
||||
std::string marker2 (" [");
|
||||
std::string marker3 (" ");
|
||||
|
||||
std::size_t found = raw.find(marker1);
|
||||
if (found != std::string::npos) {
|
||||
std::string msg = raw.substr (found + 3);
|
||||
std::string level ("FLOG_MAX");
|
||||
|
||||
found = raw.find(marker2);
|
||||
if (found != std::string::npos) {
|
||||
std::string str = raw.substr(0, found - 1);
|
||||
boost::trim_right(str);
|
||||
found = str.find(marker3);
|
||||
/* while (found != std::string::npos) {
|
||||
level = str.substr(found);
|
||||
found = str.find(marker3);
|
||||
} // */
|
||||
}
|
||||
|
||||
if (!msg.empty()) {
|
||||
GELF_MESSAGE(graylog)
|
||||
(CurrentTimeStamp())
|
||||
("pid", getpid())
|
||||
("level", level.c_str())
|
||||
(msg.c_str());
|
||||
}
|
||||
}
|
||||
// */
|
||||
}
|
||||
// */
|
||||
|
||||
|
||||
@@ -12,6 +12,14 @@
|
||||
#include <iostream>
|
||||
#include <libpq-fe.h>
|
||||
|
||||
#include <gelfcpp/decorator/StaticDecoratorSet.hpp>
|
||||
#include <gelfcpp/decorator/Timestamp.hpp>
|
||||
#include <gelfcpp/decorator/Host.hpp>
|
||||
|
||||
extern gelfcpp::output::GelfUDPOutput *graylog;
|
||||
using Decorator = gelfcpp::decorator::StaticDecoratorSet<gelfcpp::decorator::CurrentTimestamp, gelfcpp::decorator::Host>;
|
||||
extern Decorator decorator;
|
||||
|
||||
WrenchBoard::WrenchBoard() {
|
||||
|
||||
// Read config
|
||||
@@ -19,7 +27,8 @@ WrenchBoard::WrenchBoard() {
|
||||
|
||||
this->logFile = CfgReadLong("logger.file");
|
||||
// global_log_level = static_cast<TLogLevel>(CfgReadLong("logger.level"));
|
||||
global_log_level = FILELog().FromString(CfgReadChar("logger.level"));
|
||||
const char *logLevel = CfgReadChar("logger.level");
|
||||
global_log_level = FILELog::FromString(logLevel);
|
||||
FILELog().SetReportingLevel(global_log_level);
|
||||
|
||||
// Open log
|
||||
@@ -27,6 +36,18 @@ WrenchBoard::WrenchBoard() {
|
||||
this->pFile = fopen(WRENCHBOARD_LOG, "a");
|
||||
Output2FILE::Stream() = pFile;
|
||||
}
|
||||
|
||||
const char *logHost = CfgReadChar("logger.host");
|
||||
long logPort = CfgReadLong("logger.port");
|
||||
|
||||
// Instantiate remote logger (GELF)
|
||||
graylog = new gelfcpp::output::GelfUDPOutput(logHost, logPort);
|
||||
std::string msg = "Instantiate remote logger (GELF)";
|
||||
GELF_MESSAGE(*graylog)(decorator)
|
||||
(msg.c_str())
|
||||
("pid", getpid())
|
||||
("loglevel", logLevel);
|
||||
//*/
|
||||
FILE_LOG(logINFO) << "WRENCHBOARD is starting...";
|
||||
|
||||
logfmt(logINFO, "Version from config: %s", CfgReadChar("version"));
|
||||
@@ -78,6 +99,22 @@ long WrenchBoard::cfgReadLong(const char *parameter) {
|
||||
|
||||
void WrenchBoard::logMessage(const char *message) {
|
||||
FILE_LOG(logINFO) << message;
|
||||
|
||||
const char* remote_addr = std::getenv( "REMOTE_ADDR" );
|
||||
const char* server_name = std::getenv( "SERVER_NAME" );
|
||||
const char* http_cookie = std::getenv( "HTTP_COOKIE" );
|
||||
const char* query_string = std::getenv( "QUERY_STRING" );
|
||||
// const char* http_x_ff = std::getenv( "HTTP_X_FORWARDED_FOR" );
|
||||
|
||||
GELF_MESSAGE(*graylog)(decorator)
|
||||
("Environment variables")
|
||||
("pid", getpid())
|
||||
("loglevel", global_log_level)
|
||||
("REMOTE_ADDR", remote_addr)
|
||||
("SERVER_NAME", server_name)
|
||||
("HTTP_COOKIE", http_cookie)
|
||||
("QUERY_STRING", query_string);
|
||||
// ("HTTP_X_FORWARDED_FOR", http_x_ff);
|
||||
}
|
||||
|
||||
WrenchBoard::~WrenchBoard() {
|
||||
@@ -92,5 +129,9 @@ WrenchBoard::~WrenchBoard() {
|
||||
fclose(this->pFile);
|
||||
} // */
|
||||
}
|
||||
// clean-up GELF
|
||||
if (graylog) {
|
||||
delete graylog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ PHP_METHOD(WrenchBoard, __construct)
|
||||
SET_ENV( "HTTP_X_FORWARDED_FOR" );
|
||||
}
|
||||
zend_string_release(_server);
|
||||
intern->wrenchboard->logMessage("Constructor finished");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,10 +74,15 @@ PHP_METHOD(WrenchBoard, wrenchboard_api)
|
||||
wrenchboard_object *intern;
|
||||
CVars input, output;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", ¶m, ¶m_out) == FAILURE) {
|
||||
/* if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", ¶m, ¶m_out) == FAILURE) {
|
||||
// Bad parameters
|
||||
RETURN_NULL();
|
||||
}
|
||||
} */
|
||||
// https://wiki.php.net/rfc/fast_zpp
|
||||
ZEND_PARSE_PARAMETERS_START(2, 2)
|
||||
Z_PARAM_ARRAY_EX(param, 0, 1)
|
||||
Z_PARAM_ARRAY_EX(param_out, 0, 1)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
intern = Z_TSTOBJ_P(id);
|
||||
if(intern != NULL) {
|
||||
@@ -119,25 +125,33 @@ PHP_METHOD(WrenchBoard, wrenchboard_api)
|
||||
const int out_size = output.size(); // 200
|
||||
const int out_value_size = 200;
|
||||
char out_key[out_value_size], out_value[out_value_size];
|
||||
if (!output.empty()) {
|
||||
array_init(param_out);
|
||||
|
||||
if (!output.empty()) {
|
||||
// array_init(param_out); // deferences variable & nothing comes out :(
|
||||
// for ( i=output.begin(); i != output.end() && j<out_size ; i++ ) {
|
||||
while (!output.empty()) {
|
||||
bzero(out_key, out_value_size);
|
||||
bzero(out_key, out_value_size);
|
||||
bzero(out_value, out_value_size);
|
||||
i = output.begin();
|
||||
i = output.begin();
|
||||
logfmt( logINFO, "RET: %s=%s", i->first.c_str(), i->second.c_str() );
|
||||
strsafecpy( out_key, i->first.c_str(), out_value_size );
|
||||
strsafecpy( out_value, i->second.c_str(), out_value_size );
|
||||
//add_assoc_string( param_out, out_key, out_value);
|
||||
add_assoc_string_ex( param_out, out_key, strlen(out_key), out_value);
|
||||
if (strlen(out_key)>0) {
|
||||
/*
|
||||
char *str;
|
||||
str = estrdup(i->second.c_str());
|
||||
add_assoc_string( param_out, out_key, str, 0);
|
||||
*/
|
||||
//add_assoc_string( param_out, out_key, out_value);
|
||||
add_assoc_string_ex( param_out, out_key, strlen(out_key), out_value);
|
||||
}
|
||||
//SAFE_STRING
|
||||
//efree(out_value);
|
||||
output.erase(output.begin());
|
||||
}
|
||||
}
|
||||
//efree(out_value);
|
||||
output.erase(output.begin());
|
||||
}
|
||||
//RETURN_ZVAL(param_out, 0, 0); // Possible workaround to return array
|
||||
}
|
||||
logfmt( logDEBUG, "About to return %ld", retval );
|
||||
|
||||
RETURN_LONG(retval);
|
||||
}
|
||||
|
||||
@@ -214,13 +228,41 @@ PHP_METHOD(WrenchBoard, logMessage)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ // ------------------------------------------------------------------
|
||||
|
||||
// https://www.phpinternalsbook.com/php7/extensions_design/php_functions.html
|
||||
// https://github.com/php/php-src/blob/master/Zend/zend_builtin_functions_arginfo.h
|
||||
|
||||
// ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args)
|
||||
// ZEND_ARG_INFO(pass_by_ref, name)
|
||||
// ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null)
|
||||
// ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null)
|
||||
// ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null)
|
||||
// ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null)
|
||||
// ZEND_ARG_VARIADIC_INFO(pass_by_ref, name)
|
||||
// ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_string, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_api, 0, 0, 2)
|
||||
//ZEND_ARG_TYPE_INFO(1, in, IS_ARRAY, 0)
|
||||
//ZEND_ARG_TYPE_INFO(1, out, IS_ARRAY, 0)
|
||||
ZEND_ARG_ARRAY_INFO(1, in, 0)
|
||||
ZEND_ARG_ARRAY_INFO(1, out, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
// ------------------------------------------------------------------ // ------------------------------------------------------------------
|
||||
const zend_function_entry wrenchboard_methods[] = {
|
||||
PHP_ME(WrenchBoard, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
|
||||
PHP_ME(WrenchBoard, wrenchboard_api, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, cfgReadChar, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, cfgReadLong, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, logMessage, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, __construct, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
|
||||
PHP_ME(WrenchBoard, wrenchboard_api, arginfo_api, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, cfgReadChar, arginfo_string, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, cfgReadLong, arginfo_string, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(WrenchBoard, logMessage, arginfo_string, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
inline std::string NowTime();
|
||||
inline gelfcpp::decorator::CurrentTimestamp CurrentTimeStamp();
|
||||
void GraylogStream(std::string raw);
|
||||
|
||||
enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logSQL, FLOG_MAX};
|
||||
|
||||
extern TLogLevel global_log_level;
|
||||
|
||||
inline gelfcpp::decorator::CurrentTimestamp CurrentTimeStamp();
|
||||
inline std::string NowTime();
|
||||
void GraylogStream(TLogLevel level, std::string raw);
|
||||
|
||||
void logfmt( TLogLevel level, const char * format, ... );
|
||||
|
||||
template <typename T>
|
||||
@@ -71,7 +71,7 @@ Log<T>::~Log()
|
||||
}
|
||||
|
||||
// Graylog
|
||||
GraylogStream(os.str());
|
||||
GraylogStream(currentLevel, os.str());
|
||||
|
||||
os << std::endl;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user