summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@oath.com>2018-09-27 19:25:13 +0200
committerHenning Baldersheim <balder@oath.com>2018-09-27 19:25:13 +0200
commitbbfc9ef04a31a6f57f5c17316f13dbcf5daaa247 (patch)
treeb5ef1c4eec3fb54b6d8eb46407f2f3df0ec35225
parent7fcdb9d9d7de7c3d562839443badcf043380c04e (diff)
Modernise code and use smart pointers and favor std containers over homegrown specialized classes.
-rw-r--r--logd/src/logd/cmdbuf.cpp28
-rw-r--r--logd/src/logd/cmdbuf.h8
-rw-r--r--logd/src/logd/conf.cpp45
-rw-r--r--logd/src/logd/conf.h7
-rw-r--r--logd/src/logd/conn.cpp25
-rw-r--r--logd/src/logd/forward.cpp2
-rw-r--r--logd/src/logd/perform.cpp96
-rw-r--r--logd/src/logd/perform.h5
-rw-r--r--logd/src/logd/service.cpp93
-rw-r--r--logd/src/logd/service.h69
-rw-r--r--logd/src/logd/state.cpp8
-rw-r--r--logd/src/logd/state.h2
-rw-r--r--logd/src/logd/watch.cpp72
-rw-r--r--logd/src/logd/watch.h12
14 files changed, 183 insertions, 289 deletions
diff --git a/logd/src/logd/cmdbuf.cpp b/logd/src/logd/cmdbuf.cpp
index dfe5c5ee3ce..b9836b5d8b0 100644
--- a/logd/src/logd/cmdbuf.cpp
+++ b/logd/src/logd/cmdbuf.cpp
@@ -1,22 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+
+#include "cmdbuf.h"
+#include "errhandle.h"
+#include "perform.h"
#include <fcntl.h>
-#include <errno.h>
#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
#include <vespa/log/log.h>
LOG_SETUP("");
-LOG_RCSID("$Id$");
-
-#include "errhandle.h"
-#include "service.h"
-#include "forward.h"
-#include "perform.h"
-#include "cmdbuf.h"
namespace logdemon {
@@ -27,13 +18,11 @@ CmdBuf::CmdBuf()
_left(_size)
{ }
-
CmdBuf::~CmdBuf()
{
free(_buf);
}
-
bool
CmdBuf::hasCmd()
{
@@ -108,8 +97,7 @@ CmdBuf::maybeRead(int fd)
int nbflags = oflags | O_NONBLOCK;
if (fcntl(fd, F_SETFL, nbflags) != 0) {
- LOG(error, "could not fcntl logserver socket: %s",
- strerror(errno));
+ LOG(error, "could not fcntl logserver socket: %s", strerror(errno));
throw SomethingBad("fcntl failed");
}
@@ -121,8 +109,7 @@ CmdBuf::maybeRead(int fd)
extend();
}
} else if (len < 0) {
- LOG(warning, "error reading from logserver socket: %s",
- strerror(errno));
+ LOG(warning, "error reading from logserver socket: %s", strerror(errno));
throw ConnectionException("error reading");
}
fcntl(fd, F_SETFL, oflags);
@@ -149,8 +136,7 @@ CmdBuf::readFile(int fd)
return true;
}
if (len < 0) {
- LOG(error, "error reading file: %s",
- strerror(errno));
+ LOG(error, "error reading file: %s", strerror(errno));
throw SomethingBad("read failed");
}
return false;
diff --git a/logd/src/logd/cmdbuf.h b/logd/src/logd/cmdbuf.h
index 8a9bf8a1ec1..0c3fd75d07e 100644
--- a/logd/src/logd/cmdbuf.h
+++ b/logd/src/logd/cmdbuf.h
@@ -1,7 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+
namespace logdemon {
+class Performer;
+
class CmdBuf
{
private:
@@ -10,10 +13,9 @@ private:
char *_bp;
int _left;
void extend();
-
- CmdBuf(const CmdBuf& other);
- CmdBuf& operator= (const CmdBuf& other);
public:
+ CmdBuf(const CmdBuf& other) = delete;
+ CmdBuf& operator= (const CmdBuf& other) = delete;
CmdBuf();
~CmdBuf();
bool hasCmd();
diff --git a/logd/src/logd/conf.cpp b/logd/src/logd/conf.cpp
index ef1f6b73cbe..f2622ac8020 100644
--- a/logd/src/logd/conf.cpp
+++ b/logd/src/logd/conf.cpp
@@ -1,22 +1,16 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+
+#include "conf.h"
+#include "forward.h"
+#include "conn.h"
#include <fcntl.h>
-#include <errno.h>
#include <unistd.h>
-#include <time.h>
-#include <sys/stat.h>
#include <vespa/log/log.h>
LOG_SETUP("");
-LOG_RCSID("$Id$");
-#include "conn.h"
-#include "service.h"
-#include "forward.h"
-#include "conf.h"
-#include <vespa/config/common/exceptions.h>
+//#include "service.h"
+//#include <vespa/config/common/exceptions.h>
using cloud::config::log::LogdConfig;
using ns_log::Logger;
@@ -27,18 +21,15 @@ void
ConfSub::configure(std::unique_ptr<LogdConfig> cfg)
{
const LogdConfig &newconf(*cfg);
- if (newconf.logserver.host != _logServer)
- {
+ if (newconf.logserver.host != _logServer) {
if (newconf.logserver.host.size() > 255) {
- LOG(warning, "too long logserver hostname: %s",
- newconf.logserver.host.c_str());
+ LOG(warning, "too long logserver hostname: %s", newconf.logserver.host.c_str());
return;
}
strcpy(_logServer, newconf.logserver.host.c_str());
_needToConnect = true;
}
- if (newconf.logserver.use != _use_logserver)
- {
+ if (newconf.logserver.use != _use_logserver) {
_use_logserver = newconf.logserver.use;
_needToConnect = true;
}
@@ -62,26 +53,22 @@ ConfSub::configure(std::unique_ptr<LogdConfig> cfg)
if (newconf.rotate.size > 0) {
_rotate_size = newconf.rotate.size;
} else {
- LOG(config, "bad rotate.size=%d must be positive",
- newconf.rotate.size);
+ LOG(config, "bad rotate.size=%d must be positive", newconf.rotate.size);
}
if (newconf.rotate.age > 0) {
_rotate_age = newconf.rotate.age;
} else {
- LOG(config, "bad rotate.age=%d must be positive",
- newconf.rotate.age);
+ LOG(config, "bad rotate.age=%d must be positive", newconf.rotate.age);
}
if (newconf.remove.totalmegabytes > 0) {
_remove_meg = newconf.remove.totalmegabytes;
} else {
- LOG(config, "bad remove.totalmegabytes=%d must be positive",
- newconf.remove.totalmegabytes);
+ LOG(config, "bad remove.totalmegabytes=%d must be positive", newconf.remove.totalmegabytes);
}
if (newconf.remove.age > 0) {
_remove_age = newconf.remove.age;
} else {
- LOG(config, "bad remove.age=%d must be positive",
- newconf.remove.age);
+ LOG(config, "bad remove.age=%d must be positive", newconf.remove.age);
}
}
@@ -116,11 +103,9 @@ ConfSub::connectToLogserver()
int newfd = makeconn(_logServer, _logPort);
if (newfd >= 0) {
resetFileDescriptor(newfd);
- LOG(debug, "connected to logserver at %s:%d",
- _logServer, _logPort);
+ LOG(debug, "connected to logserver at %s:%d", _logServer, _logPort);
} else {
- LOG(debug, "could not connect to %s:%d",
- _logServer, _logPort);
+ LOG(debug, "could not connect to %s:%d", _logServer, _logPort);
}
}
diff --git a/logd/src/logd/conf.h b/logd/src/logd/conf.h
index a777470efc6..cf163d2dcfd 100644
--- a/logd/src/logd/conf.h
+++ b/logd/src/logd/conf.h
@@ -1,10 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+
#include <logd/config-logd.h>
#include <vespa/config/config.h>
namespace logdemon {
+class Forwarder;
+
class ConfSub {
private:
char _logServer[256];
@@ -25,12 +28,12 @@ private:
void connectToLogserver();
void connectToDevNull();
void resetFileDescriptor(int newfd);
- ConfSub(const ConfSub& other);
- ConfSub& operator=(const ConfSub& other);
public:
bool checkAvailable();
void latch();
void closeConn();
+ ConfSub(const ConfSub& other) = delete;
+ ConfSub& operator=(const ConfSub& other) = delete;
ConfSub(Forwarder &fw, const config::ConfigUri & configUri);
~ConfSub();
diff --git a/logd/src/logd/conn.cpp b/logd/src/logd/conn.cpp
index 19de80545cf..2ad9093011a 100644
--- a/logd/src/logd/conn.cpp
+++ b/logd/src/logd/conn.cpp
@@ -1,26 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <vespa/log/log.h>
-LOG_SETUP("");
-LOG_RCSID("$Id$");
-
-#include "errhandle.h"
-#include <logd/config-logd.h>
#include "conn.h"
-#include <vespa/config/common/exceptions.h>
#include <vespa/vespalib/net/socket_address.h>
+#include <vespa/log/log.h>
+LOG_SETUP("");
+
namespace logdemon {
static int retryBeforeWarningCount = 20;
@@ -38,9 +23,7 @@ int makeconn(const char *logSrvHost, int logPort)
}
return -1;
}
- LOG(debug,
- "Made new connection to port %d. Connected to daemon.",
- logPort);
+ LOG(debug, "Made new connection to port %d. Connected to daemon.", logPort);
return handle.release();
}
diff --git a/logd/src/logd/forward.cpp b/logd/src/logd/forward.cpp
index a0c4a3a003b..85fd6f3aba1 100644
--- a/logd/src/logd/forward.cpp
+++ b/logd/src/logd/forward.cpp
@@ -172,7 +172,7 @@ Forwarder::parseline(const char *linestart, const char *lineend)
}
Service *svcp = knownServices.getService(service.c_str());
- Component *cp = svcp->getComponent(component.c_str());
+ Component *cp = svcp->getComponent(component);
cp->remember(logtime, pid);
bool retval = cp->shouldForward(l);
return retval;
diff --git a/logd/src/logd/perform.cpp b/logd/src/logd/perform.cpp
index d7d086a26b9..e991e143f27 100644
--- a/logd/src/logd/perform.cpp
+++ b/logd/src/logd/perform.cpp
@@ -1,29 +1,17 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <vespa/log/log.h>
-LOG_SETUP("");
-LOG_RCSID("$Id$");
-
-#include "service.h"
-#include "forward.h"
#include "perform.h"
#include "cmdbuf.h"
+#include <cassert>
+
+#include <vespa/log/log.h>
+LOG_SETUP("");
namespace logdemon {
-Performer::~Performer()
-{
-}
+namespace {
-static bool
+bool
isPrefix(const char *prefix, const char *line)
{
while (*prefix) {
@@ -32,10 +20,11 @@ isPrefix(const char *prefix, const char *line)
return true;
}
-ExternalPerformer::~ExternalPerformer()
-{
}
+Performer::~Performer() = default;
+ExternalPerformer::~ExternalPerformer() = default;
+
void
ExternalPerformer::listStates(const char *service, const char *component)
{
@@ -56,16 +45,13 @@ ExternalPerformer::listStates(const char *service, const char *component)
levstate = "store";
}
}
- pos += snprintf(buf+pos, 1024-pos, "%s=%s,",
- Logger::logLevelNames[i],
- levstate);
+ pos += snprintf(buf+pos, 1024-pos, "%s=%s,", Logger::logLevelNames[i], levstate);
}
if (pos < 1000) {
buf[pos-1]='\n';
_forwarder.forwardText(buf, pos);
} else {
- LOG(warning, "buffer to small to list states[%s, %s]",
- service, component);
+ LOG(warning, "buffer to small to list states[%s, %s]", service, component);
}
}
@@ -73,30 +59,26 @@ void
ExternalPerformer::doCmd(char *line)
{
if (isPrefix("list services", line)) {
- ServIter it = _services._services.iterator();
- while (it.valid()) {
+ for (const auto & entry : _services._services) {
char buf[1024];
- snprintf(buf, 1024, "service %s\n", it.key());
+ snprintf(buf, 1024, "service %s\n", entry.first.c_str());
_forwarder.forwardText(buf, strlen(buf));
- it.next();
}
return;
}
if (isPrefix("list components ", line)) {
const char *servstr = line+5+11;
Service *svc = _services.getService(servstr);
- CompIter it = svc->_components.iterator();
- while (it.valid()) {
+ for (const auto & entry : svc->_components) {
+ const char * key = entry.first.c_str();
char buf[1024];
- snprintf(buf, 1024, "component %s %s\n", servstr, it.key());
+ snprintf(buf, 1024, "component %s %s\n", servstr, key);
int len = strlen(buf);
if (len < 1000) {
_forwarder.forwardText(buf, len);
} else {
- LOG(warning, "buffer too small to list component %s %s",
- servstr, it.key());
+ LOG(warning, "buffer too small to list component %s %s", servstr, key);
}
- it.next();
}
return;
}
@@ -105,10 +87,8 @@ ExternalPerformer::doCmd(char *line)
char *compstr = strchr(servstr, ' ');
if (compstr == nullptr) {
Service *svc = _services.getService(servstr);
- CompIter it = svc->_components.iterator();
- while (it.valid()) {
- listStates(servstr, it.key());
- it.next();
+ for (const auto & entry : svc->_components) {
+ listStates(servstr, entry.first.c_str());
}
return;
}
@@ -121,10 +101,9 @@ ExternalPerformer::doCmd(char *line)
if (levmods == nullptr) {
LOG(error, "bad command: %s", line);
} else {
- char *orig = strdup(line);
+ vespalib::string orig(line);
*levmods++ = '\0';
- doSetAllStates(levmods, orig);
- free(orig);
+ doSetAllStates(levmods, orig.c_str());
}
return;
}
@@ -183,12 +162,11 @@ ExternalPerformer::doCmd(char *line)
}
void
-ExternalPerformer::doSetAllStates(char *levmods, char *origline) {
+ExternalPerformer::doSetAllStates(char *levmods, const char *origline) {
while (levmods) {
char *newval = strchr(levmods, '=');
if (!newval) {
- LOG(error, "bad command %s : expected level=value, got %s",
- origline, levmods);
+ LOG(error, "bad command %s : expected level=value, got %s", origline, levmods);
return;
}
*newval++ = '\0';
@@ -196,12 +174,10 @@ ExternalPerformer::doSetAllStates(char *levmods, char *origline) {
LogLevel level = _levelparser.parseLevel(levmods);
char *nextlev = strchr(newval, ',');
if (nextlev) *nextlev++ = '\0';
- ServIter it = _services._services.iterator();
- while (it.valid()) {
- Service *svc = _services.getService(it.key());
- CompIter cit = svc->_components.iterator();
- while (cit.valid()) {
- Component *cmp = svc->getComponent(cit.key());
+ for (const auto & serviceEntry : _services._services) {
+ Service *svc = _services.getService(serviceEntry.first);
+ for (const auto & entry : svc->_components) {
+ Component *cmp = svc->getComponent(entry.first);
assert(cmp != 0);
if (strcmp(newval, "forward") == 0) {
@@ -216,14 +192,10 @@ ExternalPerformer::doSetAllStates(char *levmods, char *origline) {
cmp->dontForward(level);
cmp->dontLogAtAll(level);
} else {
- LOG(error, "bad command %s: want forward/store/off, got %s",
- origline, newval);
+ LOG(error, "bad command %s: want forward/store/off, got %s", origline, newval);
return;
}
-
- cit.next();
}
- it.next();
}
levmods = nextlev;
@@ -235,8 +207,7 @@ ExternalPerformer::doSetState(char *levmods, Component *cmp, char * line) {
while (levmods) {
char *newval = strchr(levmods, '=');
if (!newval) {
- LOG(error, "bad command %s : expected level=value, got %s",
- line, levmods);
+ LOG(error, "bad command %s : expected level=value, got %s", line, levmods);
return nullptr;
}
*newval++ = '\0';
@@ -256,8 +227,7 @@ ExternalPerformer::doSetState(char *levmods, Component *cmp, char * line) {
cmp->dontForward(level);
cmp->dontLogAtAll(level);
} else {
- LOG(error, "bad command %s %s=%s: want forward/store/off",
- line, levmods, newval);
+ LOG(error, "bad command %s %s=%s: want forward/store/off", line, levmods, newval);
return nullptr;
}
levmods = nextlev;
@@ -293,8 +263,7 @@ InternalPerformer::doCmd(char *line)
while (levmods) {
char *newval = strchr(levmods, '=');
if (!newval) {
- LOG(error, "bad internal %s %s: expected level=value, got %s",
- line, compstr, levmods);
+ LOG(error, "bad internal %s %s: expected level=value, got %s", line, compstr, levmods);
return;
}
*newval++ = '\0';
@@ -309,8 +278,7 @@ InternalPerformer::doCmd(char *line)
} else if (strcmp(newval, "off") == 0) {
cmp->dontForward(level);
} else {
- LOG(error, "bad internal %s %s %s=%s: want forward/store/off",
- line, compstr, levmods, newval);
+ LOG(error, "bad internal %s %s %s=%s: want forward/store/off", line, compstr, levmods, newval);
return;
}
levmods = nextlev;
diff --git a/logd/src/logd/perform.h b/logd/src/logd/perform.h
index 0b045c4c34e..0303360fe49 100644
--- a/logd/src/logd/perform.h
+++ b/logd/src/logd/perform.h
@@ -1,5 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+
+#include "forward.h"
+
namespace logdemon {
class Performer
@@ -20,7 +23,7 @@ private:
void listStates(const char *service, const char *component);
public:
void doCmd(char *line) override;
- void doSetAllStates(char *levmods, char * line);
+ void doSetAllStates(char *levmods, const char * line);
char *doSetState(char *levmods, Component *cmp, char *line);
ExternalPerformer(Forwarder& fw, Services& s)
: _forwarder(fw), _services(s) {}
diff --git a/logd/src/logd/service.cpp b/logd/src/logd/service.cpp
index 8084fc56416..976c7fa6ea4 100644
--- a/logd/src/logd/service.cpp
+++ b/logd/src/logd/service.cpp
@@ -1,24 +1,31 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <cstdlib>
-#include <cstring>
-#include <cstdio>
-#include <fcntl.h>
-#include <cerrno>
-#include <unistd.h>
-#include <ctime>
-#include <sys/stat.h>
+#include "service.h"
#include <cassert>
+#include <unistd.h>
#include <vespa/log/log.h>
#include <vespa/log/control-file.h>
LOG_SETUP("logdemon");
-#include "service.h"
namespace logdemon {
unsigned long Component::defFwd = (unsigned long)-1;
+Component::Component(const char *servicename, const char *name)
+ : _isforwarding(defFwd), _lastseen(0.0), _lastpid(0),
+ _myservice(servicename), _myname(name),
+ _logctlname()
+{
+ assert(ns_log::Logger::NUM_LOGLEVELS < 32);
+ const char *withoutprefix = strchr(name, '.');
+ if (withoutprefix != nullptr) {
+ _logctlname = withoutprefix;
+ }
+}
+
+Component::~Component() = default;
+
void
Component::doLogAtAll(LogLevel level)
{
@@ -31,7 +38,7 @@ Component::doLogAtAll(LogLevel level)
}
try {
ControlFile foo(lcfn, ControlFile::READWRITE);
- unsigned int *lstring = foo.getLevels(_logctlname);
+ unsigned int *lstring = foo.getLevels(_logctlname.c_str());
lstring[level] = CHARS_TO_UINT(' ', ' ', 'O', 'N');
} catch (...) {
LOG(debug, "exception changing logcontrol for %s", _myservice);
@@ -50,7 +57,7 @@ Component::dontLogAtAll(LogLevel level)
}
try {
ControlFile foo(lcfn, ControlFile::READWRITE);
- unsigned int *lstring = foo.getLevels(_logctlname);
+ unsigned int *lstring = foo.getLevels(_logctlname.c_str());
lstring[level] = CHARS_TO_UINT(' ', 'O', 'F', 'F');
} catch (...) {
LOG(debug, "exception changing logcontrol for %s", _myservice);
@@ -58,7 +65,7 @@ Component::dontLogAtAll(LogLevel level)
}
bool
-Component::shouldLogAtAll(LogLevel level)
+Component::shouldLogAtAll(LogLevel level) const
{
using ns_log::ControlFile;
@@ -69,7 +76,7 @@ Component::shouldLogAtAll(LogLevel level)
}
try {
ControlFile foo(lcfn, ControlFile::READWRITE);
- unsigned int *lstring = foo.getLevels(_logctlname);
+ unsigned int *lstring = foo.getLevels(_logctlname.c_str());
return (lstring[level] == CHARS_TO_UINT(' ', ' ', 'O', 'N'));
} catch (...) {
LOG(debug, "exception checking logcontrol for %s", _myservice);
@@ -77,55 +84,61 @@ Component::shouldLogAtAll(LogLevel level)
return true;
}
-
-Service::~Service()
+Service::Service(const char *name)
+ : _myname(name),
+ _components()
{
- CompIter it = _components.iterator();
- while (it.valid()) {
- delete it.value();
- it.next();
+}
+
+Service::~Service() = default;
+
+Component *
+Service::getComponent(const vespalib::string & comp) {
+ auto found = _components.find(comp);
+ if (found == _components.end()) {
+ _components[comp] = std::make_unique<Component>(_myname.c_str(), comp.c_str());
+ found = _components.find(comp);
}
- free(_myname);
+ return found->second.get();
}
-Services::~Services()
-{
- ServIter it = _services.iterator();
- while (it.valid()) {
- delete it.value();
- it.next();
+Service *
+Services::getService(const vespalib::string & serv) {
+ auto found = _services.find(serv);
+ if (found == _services.end()) {
+ _services[serv] = std::make_unique<Service>(serv.c_str());
+ found = _services.find(serv);
}
+ return found->second.get();
}
+Services::~Services() = default;
+
void
Services::dumpState(int fildesc)
{
using ns_log::Logger;
- ServIter sit = _services.iterator();
- while (sit.valid()) {
- Service *svc = sit.value();
- CompIter it = svc->_components.iterator();
- while (it.valid()) {
- Component *cmp = it.value();
+ for (const auto & serviceEntry : _services) {
+ const Service & svc = *serviceEntry.second;
+ const char * service = serviceEntry.first.c_str();
+ for (const auto & entry : svc._components) {
+ const Component & cmp = *entry.second;
+ const char * key = entry.first.c_str();
char buf[1024];
- int pos = snprintf(buf, 1024, "setstate %s %s ", sit.key(), it.key());
+ int pos = snprintf(buf, 1024, "setstate %s %s ", service, key);
for (int i = 0; pos < 1000 && i < Logger::NUM_LOGLEVELS; i++) {
LogLevel l = static_cast<LogLevel>(i);
- pos += snprintf(buf+pos, 1024-pos, "%s=%s,",
- Logger::logLevelNames[i],
- cmp->shouldForward(l) ? "forward" : "store");
+ pos += snprintf(buf+pos, 1024-pos, "%s=%s,", Logger::logLevelNames[i],
+ cmp.shouldForward(l) ? "forward" : "store");
}
if (pos < 1000) {
buf[pos-1]='\n';
write(fildesc, buf, pos);
} else {
- LOG(warning, "buffer to small to dumpstate[%s, %s]",
- sit.key(), it.key());
+ LOG(warning, "buffer to small to dumpstate[%s, %s]", service, key);
}
- it.next();
}
- sit.next();
}
}
diff --git a/logd/src/logd/service.h b/logd/src/logd/service.h
index 8467ce7b2a2..3dd613008b6 100644
--- a/logd/src/logd/service.h
+++ b/logd/src/logd/service.h
@@ -2,9 +2,8 @@
#pragma once
#include <logd/config-logd.h>
-#include <vespa/vespalib/util/hashmap.h>
#include <vespa/log/log.h>
-#include <cassert>
+#include <unordered_map>
namespace logdemon {
@@ -12,15 +11,12 @@ typedef ns_log::Logger::LogLevel LogLevel;
class Component
{
- unsigned long _isforwarding;
- double _lastseen;
- int _lastpid;
- const char *_myservice;
- char *_myname;
- char *_logctlname;
-
- Component(const Component& other);
- Component& operator= (const Component& other);
+ unsigned long _isforwarding;
+ double _lastseen;
+ int _lastpid;
+ const char *_myservice;
+ vespalib::string _myname;
+ vespalib::string _logctlname;
static unsigned long defFwd;
public:
@@ -29,67 +25,38 @@ public:
void doForward(LogLevel level) { _isforwarding |= (1 << level); }
void dontForward(LogLevel level) { _isforwarding &= ~(1 << level); }
- bool shouldForward(LogLevel level) {
+ bool shouldForward(LogLevel level) const {
return ((_isforwarding & (1 << level)) != 0);
}
void doLogAtAll(LogLevel level);
void dontLogAtAll(LogLevel level);
- bool shouldLogAtAll(LogLevel level);
- Component(const char *servicename, const char *name)
- : _isforwarding(defFwd), _lastseen(0.0), _lastpid(0),
- _myservice(servicename), _myname(strdup(name)),
- _logctlname(strdup(name))
- {
- assert(ns_log::Logger::NUM_LOGLEVELS < 32);
- const char *withoutprefix = strchr(name, '.');
- if (withoutprefix != nullptr) {
- strcpy(_logctlname, withoutprefix);
- } else {
- strcpy(_logctlname, "");
- }
- }
- ~Component() { free(_myname); free(_logctlname); }
+ bool shouldLogAtAll(LogLevel level) const;
+ Component(const char *servicename, const char *name);
+ ~Component();
void remember(double t, int p) { _lastseen = t; _lastpid = p; }
double lastSeen() const { return _lastseen; }
double lastPid() const { return _lastpid; }
};
-typedef vespalib::HashMap<Component *> CompMap;
-typedef vespalib::HashMap<Component *>::Iterator CompIter;
-
class Service
{
private:
- char *_myname;
+ vespalib::string _myname;
Service(const Service& other);
Service& operator= (const Service& other);
public:
- CompMap _components;
- Component *getComponent(const char *comp) {
- if (! _components.isSet(comp)) {
- _components.set(comp, new Component(_myname, comp));
- }
- return _components[comp];
- }
- Service(const char *name)
- : _myname(strdup(name)), _components(nullptr) {}
+ std::unordered_map<std::string, std::unique_ptr<Component>> _components;
+ Component *getComponent(const vespalib::string & comp);
+ Service(const char *name);
~Service();
};
-typedef vespalib::HashMap<Service *> ServMap;
-typedef vespalib::HashMap<Service *>::Iterator ServIter;
-
class Services
{
public:
- ServMap _services;
- Service *getService(const char *serv) {
- if (! _services.isSet(serv)) {
- _services.set(serv, new Service(serv));
- }
- return _services[serv];
- }
- Services() : _services(nullptr) {}
+ std::unordered_map<std::string, std::unique_ptr<Service>> _services;
+ Service *getService(const vespalib::string & serv);
+ Services() : _services() {}
~Services();
void dumpState(int fildesc);
};
diff --git a/logd/src/logd/state.cpp b/logd/src/logd/state.cpp
index e1df1412215..edea951aca7 100644
--- a/logd/src/logd/state.cpp
+++ b/logd/src/logd/state.cpp
@@ -1,11 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include <vespa/log/log.h>
-LOG_SETUP("");
-
#include "state.h"
#include <vespa/vespalib/metrics/simple_metrics_manager.h>
+#include <vespa/log/log.h>
+LOG_SETUP("");
+
namespace logdemon {
using vespalib::metrics::SimpleMetricsManager;
@@ -21,6 +21,8 @@ StateReporter::StateReporter()
{
}
+StateReporter::~StateReporter() = default;
+
void
StateReporter::setStatePort(int statePort)
{
diff --git a/logd/src/logd/state.h b/logd/src/logd/state.h
index 59c9741e68f..3bd6513dce7 100644
--- a/logd/src/logd/state.h
+++ b/logd/src/logd/state.h
@@ -19,7 +19,7 @@ class StateReporter {
vespalib::metrics::Producer _producer;
public:
StateReporter();
- ~StateReporter() {}
+ ~StateReporter();
void setStatePort(int statePort);
void gotConf(size_t generation);
std::shared_ptr<vespalib::metrics::MetricsManager> metrics() { return _metrics; }
diff --git a/logd/src/logd/watch.cpp b/logd/src/logd/watch.cpp
index d7ebeaf74ec..ec27e0ad0e1 100644
--- a/logd/src/logd/watch.cpp
+++ b/logd/src/logd/watch.cpp
@@ -1,10 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "watch.h"
#include "errhandle.h"
#include "service.h"
#include "forward.h"
#include "conf.h"
-#include "watch.h"
#include "perform.h"
#include "cmdbuf.h"
#include <glob.h>
@@ -58,25 +58,20 @@ int elapsed(struct timeval &start) {
return diffsecs;
}
+constexpr size_t G_BUFSIZE = 1024*1024;
} // namespace logdemon::<unnamed>
-static const int bufsiz = 1024*1024;
Watcher::Watcher(ConfSub &cfs, Forwarder &fw)
- : _buffer(new char[bufsiz]),
+ : _buffer(G_BUFSIZE),
_confsubscriber(cfs),
_forwarder(fw),
_wfd(-1)
{
- if (_buffer == nullptr) {
- LOG(error, "could not allocate 1MB memory");
- throw SomethingBad("out of memory");
- }
}
Watcher::~Watcher()
{
- delete[] _buffer;
if (_wfd >= 0) {
LOG(debug, "~Watcher closing %d", _wfd);
close(_wfd);
@@ -103,8 +98,7 @@ private:
int _cachecounter;
};
-void StateSaver::saveState(const donecache& already,
- Services& currentserv)
+void StateSaver::saveState(const donecache& already, Services& currentserv)
{
if (_savefd < 0) {
// cannot save state
@@ -125,8 +119,7 @@ void StateSaver::saveState(const donecache& already,
if (here == (off_t)-1) {
LOG(error, "lseek failed: %s", strerror(errno));
} else if (ftruncate(_savefd, here) < 0) {
- LOG(error, "ftruncate %d=%d failed: %s",
- _savefd, (int)here, strerror(errno));
+ LOG(error, "ftruncate %d=%d failed: %s", _savefd, (int)here, strerror(errno));
}
_cachecounter = 0;
}
@@ -155,8 +148,7 @@ StateSaver::StateSaver() : _savefd(-1), _cachecounter(300)
{
_savefd = open("var/db/vespa/logd.donestate", O_RDWR|O_CREAT, 0664);
if (_savefd < 0) {
- LOG(warning, "could not open var/db/vespa/logd.donestate: %s",
- strerror(errno));
+ LOG(warning, "could not open var/db/vespa/logd.donestate: %s", strerror(errno));
}
}
@@ -175,8 +167,7 @@ Watcher::watchfile()
char *target = getenv("VESPA_LOG_TARGET");
if (target == nullptr || strncmp(target, "file:", 5) != 0) {
- LOG(error, "expected VESPA_LOG_TARGET (%s) to be a file: target",
- target);
+ LOG(error, "expected VESPA_LOG_TARGET (%s) to be a file: target", target);
throw SomethingBad("bad log target");
}
const char *filename = target+5;
@@ -204,8 +195,7 @@ Watcher::watchfile()
// XXX should close and/or check _wfd first ?
_wfd = open(filename, O_RDONLY|O_CREAT, 0664);
if (_wfd < 0) {
- LOG(error, "open(%s) failed: %s", filename,
- strerror(errno));
+ LOG(error, "open(%s) failed: %s", filename, strerror(errno));
throw SomethingBad("could not create or open logfile");
}
@@ -216,8 +206,7 @@ Watcher::watchfile()
while (1) {
struct stat sb;
if (fstat(_wfd, &sb) != 0) {
- LOG(error, "fstat(%s) failed: %s", filename,
- strerror(errno));
+ LOG(error, "fstat(%s) failed: %s", filename, strerror(errno));
throw SomethingBad("fstat failed");
}
if (created == 0) {
@@ -236,8 +225,7 @@ Watcher::watchfile()
if (sb.st_size < offset) {
// this is bad, maybe somebody else truncated the file
- LOG(error, "file mysteriously shrunk %d -> %d",
- (int)offset, (int)sb.st_size);
+ LOG(error, "file mysteriously shrunk %d -> %d", (int)offset, (int)sb.st_size);
return;
}
@@ -246,15 +234,14 @@ Watcher::watchfile()
if (sb.st_size > offset) {
lseek(_wfd, offset, SEEK_SET);
- ssize_t rsize = read(_wfd, _buffer, bufsiz - 1);
+ char *buffer = getBuf();
+ ssize_t rsize = read(_wfd, buffer, (getBufSize() - 1));
if (rsize > 0) {
- _buffer[rsize] = '\0';
- char *l = _buffer;
- char *nnl = (char *)memchr(_buffer, '\n', rsize);
- if (nnl == nullptr && rsize == bufsiz - 1) {
- // incredibly long block without any newline ?
- LOG(error, "no newline in %ld bytes, skipping",
- static_cast<long>(rsize));
+ buffer[rsize] = '\0';
+ char *l = buffer;
+ char *nnl = (char *)memchr(buffer, '\n', rsize);
+ if (nnl == nullptr && rsize == (getBufSize() - 1)) {
+ LOG(error, "no newline in %ld bytes, skipping", static_cast<long>(rsize));
offset += rsize;
}
while (nnl != nullptr && elapsed(tickStart) < 1) {
@@ -266,8 +253,7 @@ Watcher::watchfile()
nnl = strchr(l, '\n');
}
} else {
- LOG(error, "could not read from %s: %s",
- filename, strerror(errno));
+ LOG(error, "could not read from %s: %s", filename, strerror(errno));
throw SomethingBad("read failed");
}
}
@@ -282,9 +268,7 @@ Watcher::watchfile()
if (rotate) {
int rotTime = elapsed(rotStart);
- if (rotTime > 59 ||
- (sb.st_size == offset && rotTime > 4))
- {
+ if (rotTime > 59 || (sb.st_size == offset && rotTime > 4)) {
removeOldLogs(filename);
if (sb.st_size != offset) {
LOG(warning, "logfile rotation incomplete after %d s (dropping %lu bytes)",
@@ -314,16 +298,14 @@ Watcher::watchfile()
int l = strlen(filename);
strcpy(newfn, filename);
struct tm *nowtm = gmtime(&now);
- if (strftime(newfn+l, FILENAME_MAX-l-1,
- "-%Y-%m-%d.%H-%M-%S", nowtm) < 10)
+ if (strftime(newfn+l, FILENAME_MAX-l-1, "-%Y-%m-%d.%H-%M-%S", nowtm) < 10)
{
LOG(error, "could not strftime");
throw SomethingBad("strftime failed");
}
if (rename(filename, newfn) != 0) {
- LOG(error, "could not rename logfile %s -> %s: %s",
- filename, newfn, strerror(errno));
+ LOG(error, "could not rename logfile %s -> %s: %s", filename, newfn, strerror(errno));
throw SomethingBad("rename failed");
} else {
LOG(debug, "old logfile name: %s", newfn);
@@ -355,8 +337,7 @@ Watcher::watchfile()
}
if (++sleepcount > 99) {
if (_forwarder._badLines) {
- LOG(info, "seen %d bad loglines in %d iterations",
- _forwarder._badLines, sleepcount);
+ LOG(info, "seen %d bad loglines in %d iterations", _forwarder._badLines, sleepcount);
_forwarder._badLines = 0;
sleepcount=0;
}
@@ -416,14 +397,11 @@ Watcher::removeOldLogs(const char *prefix)
continue;
}
totalsize += sb.st_size;
- if (totalsize > (_confsubscriber.getRemoveMegabytes()
- * 1048576LL))
+ if (totalsize > (_confsubscriber.getRemoveMegabytes() * 1048576LL))
{
- LOG(info, "removing %s, total size (%ld) too big",
- fname, static_cast<int64_t>(totalsize));
+ LOG(info, "removing %s, total size (%ld) too big", fname, static_cast<int64_t>(totalsize));
if (unlink(fname) != 0) {
- LOG(warning, "cannot remove %s: %s",
- fname, strerror(errno));
+ LOG(warning, "cannot remove %s: %s", fname, strerror(errno));
}
}
} else {
diff --git a/logd/src/logd/watch.h b/logd/src/logd/watch.h
index 67616b18a48..bcac6046b6f 100644
--- a/logd/src/logd/watch.h
+++ b/logd/src/logd/watch.h
@@ -1,6 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+#include <vector>
+
namespace logdemon {
class Forwarder;
@@ -9,10 +11,12 @@ class ConfSub;
class Watcher
{
private:
- char *_buffer;
- ConfSub& _confsubscriber;
- Forwarder& _forwarder;
- int _wfd;
+ std::vector<char> _buffer;
+ ConfSub & _confsubscriber;
+ Forwarder & _forwarder;
+ int _wfd;
+ char * getBuf() { return &_buffer[0]; }
+ long getBufSize() const { return _buffer.size(); }
public:
Watcher(const Watcher& other) = delete;
Watcher& operator=(const Watcher& other) = delete;