move functionality from VerboseLoggingHelper into the Logging class

This commit is contained in:
Stephen Birarda 2014-10-28 13:48:53 -07:00
parent 8a4c716452
commit 2711ff2b5f
6 changed files with 38 additions and 155 deletions

View file

@ -581,10 +581,6 @@ void Application::initializeGL() {
float startupTime = (float)_applicationStartupTime.elapsed() / 1000.0;
_justStarted = false;
qDebug("Startup time: %4.2f seconds.", startupTime);
const char LOGSTASH_INTERFACE_START_TIME_KEY[] = "interface-start-time";
// ask the Logstash class to record the startup time
Logging::stashValue(STAT_TYPE_TIMER, LOGSTASH_INTERFACE_START_TIME_KEY, startupTime);
}
// update before the first render

View file

@ -19,8 +19,6 @@
#include <QtCore/QUrl>
#include <QtNetwork/QHostInfo>
#include <VerboseLoggingHelper.h>
#include "AccountManager.h"
#include "Assignment.h"
#include "HifiSockAddr.h"
@ -213,10 +211,8 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) {
<< uuidFromPacketHeader(packet);
}
} else {
QString unknownPacketString = "%1 packets of type " + QString::number(checkType)
+ " received from unknown node with UUID "
+ uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet));
VerboseLoggingHelper::getInstance().addMessage(unknownPacketString);
qDebug() << "Packet of type" << checkType << "received from unknown node with UUID"
<< uuidStringWithoutCurlyBraces(uuidFromPacketHeader(packet));
}
} else {
return true;

View file

@ -9,12 +9,6 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <cstring>
#include <cstdio>
#include <iostream>
#include <ctime>
//#include <netdb.h> // not available on windows, apparently not needed on mac
#ifdef _WIN32
#include <process.h>
#define getpid _getpid
@ -22,55 +16,22 @@
#define pid_t int // hack to build
#endif
#include <QtNetwork/QHostInfo>
#include "HifiSockAddr.h"
#include "SharedUtil.h"
#include "NodeList.h"
#include <qtimer.h>
#include "Logging.h"
HifiSockAddr Logging::_logstashSocket = HifiSockAddr();
QString Logging::_targetName = QString();
const HifiSockAddr& Logging::socket() {
if (_logstashSocket.getAddress().isNull()) {
// we need to construct the socket object
// use the constant port
_logstashSocket.setPort(htons(LOGSTASH_UDP_PORT));
// lookup the IP address for the constant hostname
QHostInfo hostInfo = QHostInfo::fromName(LOGSTASH_HOSTNAME);
if (!hostInfo.addresses().isEmpty()) {
// use the first IP address
_logstashSocket.setAddress(hostInfo.addresses().first());
} else {
qDebug("Failed to lookup logstash IP - will try again on next log attempt.");
}
}
return _logstashSocket;
Logging& Logging::getInstance() {
static Logging staticInstance;
return staticInstance;
}
bool Logging::shouldSendStats() {
static bool shouldSendStats = isInEnvironment("production");
return shouldSendStats;
}
void Logging::stashValue(char statType, const char* key, float value) {
static char logstashPacket[MAX_PACKET_SIZE];
// load up the logstash packet with the key and the passed float value
// send it to 4 decimal places
int numPacketBytes = sprintf(logstashPacket, "%c %s %.4f", statType, key, value);
NodeList *nodeList = NodeList::getInstance();
if (nodeList) {
nodeList->getNodeSocket().writeDatagram(logstashPacket, numPacketBytes,
_logstashSocket.getAddress(), _logstashSocket.getPort());
}
Logging::Logging() {
// setup our timer to flush the verbose logs every 5 seconds
QTimer* logFlushTimer = new QTimer(this);
connect(logFlushTimer, &QTimer::timeout, this, &Logging::flushRepeatedMessages);
logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000);
}
const char* stringForLogType(QtMsgType msgType) {
@ -95,6 +56,7 @@ void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& co
if (message.isEmpty()) {
return;
}
// log prefix is in the following format
// [DEBUG] [TIMESTAMP] [PID:PARENT_PID] [TARGET] logged string
@ -118,9 +80,16 @@ void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& co
prefixString.append("]");
}
if (!_targetName.isEmpty()) {
prefixString.append(QString(" [%1]").arg(_targetName));
if (!getInstance()._targetName.isEmpty()) {
prefixString.append(QString(" [%1]").arg(getInstance()._targetName));
}
fprintf(stdout, "%s %s\n", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData());
}
void Logging::flushRepeatedMessages() {
QHash<QString, int>::iterator message = _repeatMessageCountHash.begin();
while (message != _repeatMessageCountHash.end()) {
message = _repeatMessageCountHash.erase(message);
}
}

View file

@ -12,33 +12,18 @@
#ifndef hifi_Logging_h
#define hifi_Logging_h
#include <QtCore/QString>
#include <qhash.h>
#include <qobject.h>
#include <qregexp.h>
#include <qset.h>
#include <qstring.h>
const int LOGSTASH_UDP_PORT = 9500;
const char LOGSTASH_HOSTNAME[] = "graphite.highfidelity.io";
const char STAT_TYPE_TIMER = 't';
const char STAT_TYPE_COUNTER = 'c';
const char STAT_TYPE_GAUGE = 'g';
class HifiSockAddr;
const int VERBOSE_LOG_INTERVAL_SECONDS = 5;
/// Handles custom message handling and sending of stats/logs to Logstash instance
class Logging {
class Logging : public QObject {
Q_OBJECT
public:
/// \return the socket used to send stats to logstash
static const HifiSockAddr& socket();
/// checks if this target should send stats to logstash, given its current environment
/// \return true if the caller should send stats to logstash
static bool shouldSendStats();
/// stashes a float value to Logstash instance
/// \param statType a stat type from the constants in this file
/// \param key the key at which to store the stat
/// \param value the value to store
static void stashValue(char statType, const char* key, float value);
/// sets the target name to output via the verboseMessageHandler, called once before logging begins
/// \param targetName the desired target name to output in logs
static void setTargetName(const QString& targetName) { _targetName = targetName; }
@ -46,9 +31,17 @@ public:
/// a qtMessageHandler that can be hooked up to a target that links to Qt
/// prints various process, message type, and time information
static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message);
static void addRepeatedMessageRegex(const QRegExp& regex) { getInstance()._repeatedMessageRegexes.append(regex); }
private:
static HifiSockAddr _logstashSocket;
static Logging& getInstance();
Logging();
void flushRepeatedMessages();
static QString _targetName;
QList<QRegExp> _repeatedMessageRegexes;
QHash<QString, int> _repeatMessageCountHash;
};
#endif // hifi_Logging_h

View file

@ -1,35 +0,0 @@
//
// VerboseLoggingHelper.cpp
// libraries/shared/src
//
// Created by Stephen Birarda on 2014-10-28.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <qdebug.h>
#include "VerboseLoggingHelper.h"
VerboseLoggingHelper& VerboseLoggingHelper::getInstance() {
static VerboseLoggingHelper sharedInstance;
return sharedInstance;
}
VerboseLoggingHelper::VerboseLoggingHelper() {
// setup our timer to flush the verbose logs every 5 seconds
_timer = new QTimer(this);
connect(_timer, &QTimer::timeout, this, &VerboseLoggingHelper::flushMessages);
_timer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000);
}
void VerboseLoggingHelper::flushMessages() {
QHash<QString, int>::iterator message = _messageCountHash.begin();
while (message != _messageCountHash.end()) {
qDebug() << qPrintable(message.key().arg(message.value()))
<< "in last" << VERBOSE_LOG_INTERVAL_SECONDS << "seconds.";
message = _messageCountHash.erase(message);
}
}

View file

@ -1,36 +0,0 @@
//
// VerboseLoggingHelper.h
// libraries/shared/src
//
// Created by Stephen Birarda on 2014-10-28.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_VerboseLoggingHelper_h
#define hifi_VerboseLoggingHelper_h
#include <qhash.h>
#include <qobject.h>
#include <qtimer.h>
const int VERBOSE_LOG_INTERVAL_SECONDS = 5;
class VerboseLoggingHelper : public QObject {
Q_OBJECT
public:
static VerboseLoggingHelper& getInstance();
void addMessage(const QString& message) { _messageCountHash[message] += 1; }
private:
VerboseLoggingHelper();
void flushMessages();
QTimer* _timer;
QHash<QString, int> _messageCountHash;
};
#endif // hifi_VerboseLoggingHelper_h