diff options
author | Henning Baldersheim <balder@oath.com> | 2018-09-27 19:25:13 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@oath.com> | 2018-09-27 19:25:13 +0200 |
commit | bbfc9ef04a31a6f57f5c17316f13dbcf5daaa247 (patch) | |
tree | b5ef1c4eec3fb54b6d8eb46407f2f3df0ec35225 /logd | |
parent | 7fcdb9d9d7de7c3d562839443badcf043380c04e (diff) |
Modernise code and use smart pointers and favor std containers over homegrown specialized classes.
Diffstat (limited to 'logd')
-rw-r--r-- | logd/src/logd/cmdbuf.cpp | 28 | ||||
-rw-r--r-- | logd/src/logd/cmdbuf.h | 8 | ||||
-rw-r--r-- | logd/src/logd/conf.cpp | 45 | ||||
-rw-r--r-- | logd/src/logd/conf.h | 7 | ||||
-rw-r--r-- | logd/src/logd/conn.cpp | 25 | ||||
-rw-r--r-- | logd/src/logd/forward.cpp | 2 | ||||
-rw-r--r-- | logd/src/logd/perform.cpp | 96 | ||||
-rw-r--r-- | logd/src/logd/perform.h | 5 | ||||
-rw-r--r-- | logd/src/logd/service.cpp | 93 | ||||
-rw-r--r-- | logd/src/logd/service.h | 69 | ||||
-rw-r--r-- | logd/src/logd/state.cpp | 8 | ||||
-rw-r--r-- | logd/src/logd/state.h | 2 | ||||
-rw-r--r-- | logd/src/logd/watch.cpp | 72 | ||||
-rw-r--r-- | logd/src/logd/watch.h | 12 |
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; |