diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2018-09-28 13:19:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-28 13:19:48 +0200 |
commit | ec2f6f0fd57236fe940926f70f3c164f1c9011bd (patch) | |
tree | d33674cc163009f87ac9651845ae0c607afb2b2d | |
parent | ae21f54bf5ec9e4b730438fa282241bd271c3ec6 (diff) | |
parent | 59cca73873423b3eed6d4c569f7e8b4db48ed78e (diff) |
Merge pull request #7135 from vespa-engine/balder/minor-cleanup-of-logd
Balder/minor cleanup of logd
-rw-r--r-- | configd/src/apps/sentinel/config-handler.h | 1 | ||||
-rw-r--r-- | documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp | 8 | ||||
-rw-r--r-- | documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp | 7 | ||||
-rw-r--r-- | logd/src/apps/logd/main.cpp | 3 | ||||
-rw-r--r-- | logd/src/logd/cmdbuf.cpp | 32 | ||||
-rw-r--r-- | logd/src/logd/cmdbuf.h | 8 | ||||
-rw-r--r-- | logd/src/logd/conf.cpp | 58 | ||||
-rw-r--r-- | logd/src/logd/conf.h | 9 | ||||
-rw-r--r-- | logd/src/logd/conn.cpp | 25 | ||||
-rw-r--r-- | logd/src/logd/errhandle.h | 11 | ||||
-rw-r--r-- | logd/src/logd/forward.cpp | 68 | ||||
-rw-r--r-- | logd/src/logd/forward.h | 14 | ||||
-rw-r--r-- | logd/src/logd/metrics.cpp | 23 | ||||
-rw-r--r-- | logd/src/logd/metrics.h | 20 | ||||
-rw-r--r-- | logd/src/logd/perform.cpp | 116 | ||||
-rw-r--r-- | logd/src/logd/perform.h | 5 | ||||
-rw-r--r-- | logd/src/logd/service.cpp | 117 | ||||
-rw-r--r-- | logd/src/logd/service.h | 77 | ||||
-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 | 86 | ||||
-rw-r--r-- | logd/src/logd/watch.h | 23 | ||||
-rw-r--r-- | logd/src/tests/forward/forward.cpp | 1 |
23 files changed, 296 insertions, 426 deletions
diff --git a/configd/src/apps/sentinel/config-handler.h b/configd/src/apps/sentinel/config-handler.h index d294d97cff9..eb22b7fada1 100644 --- a/configd/src/apps/sentinel/config-handler.h +++ b/configd/src/apps/sentinel/config-handler.h @@ -6,7 +6,6 @@ #include "state-api.h" #include <vespa/config-sentinel.h> #include <vespa/config/config.h> -#include <vespa/vespalib/util/hashmap.h> #include <sys/types.h> #include <sys/select.h> diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp index 4f54c0c5bac..42e1c07f3e8 100644 --- a/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp +++ b/documentapi/src/vespa/documentapi/messagebus/policies/localservicepolicy.cpp @@ -4,7 +4,6 @@ #include <vespa/documentapi/messagebus/documentprotocol.h> #include <vespa/messagebus/routing/verbatimdirective.h> #include <vespa/messagebus/messagebus.h> -#include <vespa/vespalib/util/hashmap.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/log/log.h> LOG_SETUP(".localservicepolicy"); @@ -16,7 +15,6 @@ LocalServicePolicy::CacheEntry::CacheEntry() : _generation(0), _recipients() { - // empty } LocalServicePolicy::LocalServicePolicy(const string ¶m) : @@ -24,13 +22,9 @@ LocalServicePolicy::LocalServicePolicy(const string ¶m) : _address(param), _cache() { - // empty } -LocalServicePolicy::~LocalServicePolicy() -{ - // empty -} +LocalServicePolicy::~LocalServicePolicy() = default; void LocalServicePolicy::select(mbus::RoutingContext &ctx) diff --git a/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp b/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp index af7e2e67661..7e2d54f318f 100644 --- a/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp +++ b/documentapi/src/vespa/documentapi/messagebus/policies/subsetservicepolicy.cpp @@ -4,8 +4,8 @@ #include <vespa/documentapi/messagebus/documentprotocol.h> #include <vespa/messagebus/routing/verbatimdirective.h> #include <vespa/messagebus/messagebus.h> -#include <vespa/vespalib/util/hashmap.h> #include <vespa/vespalib/util/stringfmt.h> +#include <vespa/vespalib/stllike/hash_fun.h> #include <vespa/log/log.h> LOG_SETUP(".subsetservicepolicy"); @@ -37,10 +37,7 @@ SubsetServicePolicy::SubsetServicePolicy(const string ¶m) : } } -SubsetServicePolicy::~SubsetServicePolicy() -{ - // empty -} +SubsetServicePolicy::~SubsetServicePolicy() = default; void SubsetServicePolicy::select(mbus::RoutingContext &context) diff --git a/logd/src/apps/logd/main.cpp b/logd/src/apps/logd/main.cpp index f9d760c4d18..62f1e48b233 100644 --- a/logd/src/apps/logd/main.cpp +++ b/logd/src/apps/logd/main.cpp @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <logd/errhandle.h> -#include <logd/service.h> #include <logd/forward.h> #include <logd/conf.h> #include <logd/watch.h> @@ -15,8 +14,6 @@ #include <vespa/log/log.h> LOG_SETUP("logdemon"); - - using namespace logdemon; using config::FileSpec; diff --git a/logd/src/logd/cmdbuf.cpp b/logd/src/logd/cmdbuf.cpp index 37915446f2d..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() { @@ -77,7 +66,7 @@ CmdBuf::extend() _size *= 2; int pos = _bp - _buf; char *nbuf = (char *)realloc(_buf, _size); - if (nbuf == NULL) { + if (nbuf == nullptr) { free(_buf); LOG(error, "could not allocate %d bytes", _size); throw SomethingBad("realloc failed"); @@ -102,14 +91,13 @@ CmdBuf::maybeRead(int fd) FD_ZERO(&fdset); FD_SET(fd, &fdset); - while (select(fd + 1, &fdset, NULL, NULL, ¬ime) > 0) { + while (select(fd + 1, &fdset, nullptr, nullptr, ¬ime) > 0) { // usually loops just once int oflags = fcntl(fd, F_GETFL); 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..f01ee8141fc 100644 --- a/logd/src/logd/conf.cpp +++ b/logd/src/logd/conf.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 "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> using cloud::config::log::LogdConfig; using ns_log::Logger; @@ -27,18 +18,11 @@ void ConfSub::configure(std::unique_ptr<LogdConfig> cfg) { const LogdConfig &newconf(*cfg); - if (newconf.logserver.host != _logServer) - { - if (newconf.logserver.host.size() > 255) { - LOG(warning, "too long logserver hostname: %s", - newconf.logserver.host.c_str()); - return; - } - strcpy(_logServer, newconf.logserver.host.c_str()); + if (newconf.logserver.host != _logServer) { + _logServer = newconf.logserver.host; _needToConnect = true; } - if (newconf.logserver.use != _use_logserver) - { + if (newconf.logserver.use != _use_logserver) { _use_logserver = newconf.logserver.use; _needToConnect = true; } @@ -62,26 +46,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); } } @@ -113,14 +93,12 @@ ConfSub::latch() void ConfSub::connectToLogserver() { - int newfd = makeconn(_logServer, _logPort); + int newfd = makeconn(_logServer.c_str(), _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.c_str(), _logPort); } else { - LOG(debug, "could not connect to %s:%d", - _logServer, _logPort); + LOG(debug, "could not connect to %s:%d", _logServer.c_str(), _logPort); } } @@ -156,7 +134,8 @@ ConfSub::closeConn() } ConfSub::ConfSub(Forwarder &fw, const config::ConfigUri & configUri) - : _logPort(0), + : _logServer(), + _logPort(0), _logserverfd(-1), _statePort(0), _rotate_size(INT_MAX), @@ -170,18 +149,17 @@ ConfSub::ConfSub(Forwarder &fw, const config::ConfigUri & configUri) _hasAvailable(false), _needToConnect(true) { - _logServer[0] = '\0'; _handle = _subscriber.subscribe<LogdConfig>(configUri.getConfigId()); _subscriber.nextConfig(0); configure(_handle->getConfig()); - LOG(debug, "got logServer %s", _logServer); + LOG(debug, "got logServer %s", _logServer.c_str()); LOG(debug, "got handle %p", _handle.get()); } ConfSub::~ConfSub() { - LOG(debug, "forget logServer %s", _logServer); + LOG(debug, "forget logServer %s", _logServer.c_str()); LOG(debug, "done ~ConfSub()"); } diff --git a/logd/src/logd/conf.h b/logd/src/logd/conf.h index a777470efc6..894070fff43 100644 --- a/logd/src/logd/conf.h +++ b/logd/src/logd/conf.h @@ -1,13 +1,16 @@ // 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]; + std::string _logServer; int _logPort; int _logserverfd; int _statePort; @@ -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/errhandle.h b/logd/src/logd/errhandle.h index 376005661fe..b2ff3516b69 100644 --- a/logd/src/logd/errhandle.h +++ b/logd/src/logd/errhandle.h @@ -1,16 +1,17 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once + #include <stdexcept> -#include <vespa/vespalib/stllike/string.h> +#include <string> namespace logdemon { class MsgException : public std::exception { private: - vespalib::string _string; + std::string _string; public: - MsgException(const char *s) : _string(s) {} - virtual ~MsgException() throw() {} + MsgException(const std::string & s) : _string(s) {} + ~MsgException() override {} const char *what() const throw() override { return _string.c_str(); } }; @@ -32,4 +33,4 @@ public: SomethingBad(const char *s) : MsgException(s) {} }; -} // namespace +} diff --git a/logd/src/logd/forward.cpp b/logd/src/logd/forward.cpp index eba38dbcbd3..1abf6bffe58 100644 --- a/logd/src/logd/forward.cpp +++ b/logd/src/logd/forward.cpp @@ -2,6 +2,7 @@ #include "forward.h" #include "errhandle.h" +#include "metrics.h" #include <vespa/vespalib/component/vtag.h> #include <vespa/vespalib/locale/c.h> #include <unistd.h> @@ -19,7 +20,7 @@ Forwarder::Forwarder(Metrics &metrics) knownServices(), _badLines(0) {} -Forwarder::~Forwarder() {} +Forwarder::~Forwarder() = default; void Forwarder::forwardText(const char *text, int len) @@ -44,7 +45,7 @@ Forwarder::sendMode() snprintf(buf, 1024, "mode logd %s\n", vespalib::VersionTag); int len = strlen(buf); if (len < 100) { - forwardText(buf, len); + forwardText(buf, len); } else { LOG(warning, "too long mode line: %s", buf); } @@ -68,16 +69,13 @@ Forwarder::forwardLine(const char *line, const char *eol) bool Forwarder::parseline(const char *linestart, const char *lineend) { - using vespalib::string; - int llength = lineend - linestart; const char *fieldstart = linestart; // time const char *tab = strchr(fieldstart, '\t'); - if (tab == NULL || tab == fieldstart) { - LOG(spam, "bad logline no 1. tab: %.*s", - llength, linestart); + if (tab == nullptr || tab == fieldstart) { + LOG(spam, "bad logline no 1. tab: %.*s", llength, linestart); ++_badLines; return false; } @@ -85,23 +83,20 @@ Forwarder::parseline(const char *linestart, const char *lineend) double logtime = vespalib::locale::c::strtod(fieldstart, &eod); if (eod != tab) { int fflen = tab - linestart; - LOG(spam, "bad logline first field not strtod parsable: %.*s", - fflen, linestart); + LOG(spam, "bad logline first field not strtod parsable: %.*s", fflen, linestart); ++_badLines; return false; } - time_t now = time(NULL); + time_t now = time(nullptr); if (logtime - 864000 > now) { int fflen = tab - linestart; - LOG(warning, "bad logline, time %.*s > 10 days in the future", - fflen, linestart); + LOG(warning, "bad logline, time %.*s > 10 days in the future", fflen, linestart); ++_badLines; return false; } if (logtime + 8640000 < now) { int fflen = tab - linestart; - LOG(warning, "bad logline, time %.*s > 100 days in the past", - fflen, linestart); + LOG(warning, "bad logline, time %.*s > 100 days in the past", fflen, linestart); ++_badLines; return false; } @@ -109,9 +104,8 @@ Forwarder::parseline(const char *linestart, const char *lineend) // hostname fieldstart = tab + 1; tab = strchr(fieldstart, '\t'); - if (tab == NULL) { - LOG(spam, "bad logline no 2. tab: %.*s", - llength, linestart); + if (tab == nullptr) { + LOG(spam, "bad logline no 2. tab: %.*s", llength, linestart); ++_badLines; return false; } @@ -119,9 +113,8 @@ Forwarder::parseline(const char *linestart, const char *lineend) // pid fieldstart = tab + 1; tab = strchr(fieldstart, '\t'); - if (tab == NULL || tab == fieldstart) { - LOG(spam, "bad logline no 3. tab: %.*s", - llength, linestart); + if (tab == nullptr || tab == fieldstart) { + LOG(spam, "bad logline no 3. tab: %.*s", llength, linestart); return false; } int pid = strtol(fieldstart, &eod, 10); @@ -130,45 +123,40 @@ Forwarder::parseline(const char *linestart, const char *lineend) // service fieldstart = tab + 1; tab = strchr(fieldstart, '\t'); - if (tab == NULL) { - LOG(spam, "bad logline no 4. tab: %.*s", - llength, linestart); + if (tab == nullptr) { + LOG(spam, "bad logline no 4. tab: %.*s", llength, linestart); ++_badLines; return false; } if (tab == fieldstart) { - LOG(spam, "empty service in logline: %.*s", - llength, linestart); + LOG(spam, "empty service in logline: %.*s", llength, linestart); } - string service(fieldstart, tab-fieldstart); + std::string service(fieldstart, tab-fieldstart); // component fieldstart = tab + 1; tab = strchr(fieldstart, '\t'); - if (tab == NULL || tab == fieldstart) { - LOG(spam, "bad logline no 5. tab: %.*s", - llength, linestart); + if (tab == nullptr || tab == fieldstart) { + LOG(spam, "bad logline no 5. tab: %.*s", llength, linestart); ++_badLines; return false; } - string component(fieldstart, tab-fieldstart); + std::string component(fieldstart, tab-fieldstart); // level fieldstart = tab + 1; tab = strchr(fieldstart, '\t'); - if (tab == NULL || tab == fieldstart) { - LOG(spam, "bad logline no 6. tab: %.*s", - llength, linestart); + if (tab == nullptr || tab == fieldstart) { + LOG(spam, "bad logline no 6. tab: %.*s", llength, linestart); ++_badLines; return false; } - string level(fieldstart, tab-fieldstart); + std::string level(fieldstart, tab-fieldstart); LogLevel l = _levelparser.parseLevel(level.c_str()); // rest is freeform message, must be on this line: if (tab > lineend) { - LOG(spam, "bad logline last tab after end: %.*s", - llength, linestart); + LOG(spam, "bad logline last tab after end: %.*s", llength, linestart); ++_badLines; return false; } @@ -181,8 +169,8 @@ Forwarder::parseline(const char *linestart, const char *lineend) return found->second; } - Service *svcp = knownServices.getService(service.c_str()); - Component *cp = svcp->getComponent(component.c_str()); + Service *svcp = knownServices.getService(service); + Component *cp = svcp->getComponent(component); cp->remember(logtime, pid); bool retval = cp->shouldForward(l); return retval; @@ -197,9 +185,9 @@ LevelParser::parseLevel(const char *level) if (l >= 0 && l <= Logger::NUM_LOGLEVELS) { return l; } - if (! _seenLevelMap[level]) { + if (_seenLevelMap.find(level) == _seenLevelMap.end()) { LOG(warning, "unknown level '%s'", level); - _seenLevelMap.set(level, true); + _seenLevelMap.insert(level); } return Logger::fatal; } diff --git a/logd/src/logd/forward.h b/logd/src/logd/forward.h index e012db205fe..78e63500295 100644 --- a/logd/src/logd/forward.h +++ b/logd/src/logd/forward.h @@ -1,15 +1,17 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once + #include "service.h" -#include "metrics.h" -#include <vespa/vespalib/util/hashmap.h> #include <map> +#include <unordered_set> namespace logdemon { -typedef vespalib::HashMap<bool> SeenMap; +using SeenMap = std::unordered_set<std::string>; // Mapping saying if a level should be forwarded or not -typedef std::map<ns_log::Logger::LogLevel, bool> ForwardMap; +using ForwardMap = std::map<ns_log::Logger::LogLevel, bool>; + +class Metrics; class LevelParser { @@ -17,7 +19,7 @@ private: SeenMap _seenLevelMap; public: ns_log::Logger::LogLevel parseLevel(const char *level); - LevelParser() : _seenLevelMap(false) {} + LevelParser() : _seenLevelMap() {} }; class Forwarder @@ -48,4 +50,4 @@ public: void sendMode(); }; -} // namespace +} diff --git a/logd/src/logd/metrics.cpp b/logd/src/logd/metrics.cpp index 1a70a2226e2..edfa44021d5 100644 --- a/logd/src/logd/metrics.cpp +++ b/logd/src/logd/metrics.cpp @@ -1,3 +1,26 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "metrics.h" + +namespace logdemon { + +Metrics::Metrics(std::shared_ptr<MetricsManager> m) + : metrics(std::move(m)), + loglevel(metrics->dimension("loglevel")), + servicename(metrics->dimension("service")), + loglines(metrics->counter("logd.processed.lines", + "how many log lines have been processed")) +{} + +Metrics::~Metrics() = default; + +void +Metrics::countLine(const vespalib::string &level, const vespalib::string &service) const +{ + Point p = metrics->pointBuilder() + .bind(loglevel, level) + .bind(servicename, service); + loglines.add(1, p); +} + +} diff --git a/logd/src/logd/metrics.h b/logd/src/logd/metrics.h index b5bc5a7dcd7..5a1a577cbf7 100644 --- a/logd/src/logd/metrics.h +++ b/logd/src/logd/metrics.h @@ -16,24 +16,10 @@ struct Metrics { const Dimension servicename; const Counter loglines; - Metrics(std::shared_ptr<MetricsManager> m) - : metrics(m), - loglevel(metrics->dimension("loglevel")), - servicename(metrics->dimension("service")), - loglines(metrics->counter("logd.processed.lines", - "how many log lines have been processed")) - {} + Metrics(std::shared_ptr<MetricsManager> m); + ~Metrics(); - ~Metrics() {} - - void countLine(const vespalib::string &level, - const vespalib::string &service) const - { - Point p = metrics->pointBuilder() - .bind(loglevel, level) - .bind(servicename, service); - loglines.add(1, p); - } + void countLine(const vespalib::string &level, const vespalib::string &service) const; }; } // namespace logdemon diff --git a/logd/src/logd/perform.cpp b/logd/src/logd/perform.cpp index fdda358a365..07afac88841 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,42 +59,36 @@ 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; } if (isPrefix("list states ", line)) { char *servstr = line+5+7; char *compstr = strchr(servstr, ' '); - if (compstr == NULL) { + 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; } @@ -118,26 +98,25 @@ ExternalPerformer::doCmd(char *line) } if (isPrefix("setallstates", line)) { char *levmods = strchr(line, ' '); - if (levmods == NULL) { + if (levmods == nullptr) { LOG(error, "bad command: %s", line); } else { - char *orig = strdup(line); + std::string orig(line); *levmods++ = '\0'; - doSetAllStates(levmods, orig); - free(orig); + doSetAllStates(levmods, orig.c_str()); } return; } if (isPrefix("setstate ", line)) { char *servstr = line + 9; char *compstr = strchr(servstr, ' '); - if (compstr == NULL) { + if (compstr == nullptr) { LOG(error, "bad command: %s", line); return; } *compstr++ = '\0'; char *levmods = strchr(compstr, ' '); - if (levmods == NULL) { + if (levmods == nullptr) { LOG(error, "bad command: %s %s", line, compstr); return; } @@ -145,7 +124,7 @@ ExternalPerformer::doCmd(char *line) Service *svc = _services.getService(servstr); Component *cmp = svc->getComponent(compstr); - if (doSetState(levmods, cmp, line) == NULL) return; + if (doSetState(levmods, cmp, line) == nullptr) return; // maybe ??? listStates(servstr, compstr); @@ -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,9 +207,8 @@ 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); - return NULL; + LOG(error, "bad command %s : expected level=value, got %s", line, levmods); + return nullptr; } *newval++ = '\0'; @@ -256,9 +227,8 @@ 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); - return NULL; + LOG(error, "bad command %s %s=%s: want forward/store/off", line, levmods, newval); + return nullptr; } levmods = nextlev; } @@ -271,20 +241,20 @@ InternalPerformer::doCmd(char *line) if (isPrefix("setstate ", line)){ char *servstr = line + 9; char *compstr = strchr(servstr, ' '); - if (compstr == NULL) { + if (compstr == nullptr) { LOG(error, "bad internal command: %s", line); return; } *compstr++ = '\0'; char *levmods = strchr(compstr, ' '); - if (levmods == NULL) { + if (levmods == nullptr) { LOG(error, "bad internal command: %s %s", line, compstr); return; } *levmods++ = '\0'; // ignore services with slash in the name, invalid - if (strchr(servstr, '/') != NULL) + if (strchr(servstr, '/') != nullptr) return; Service *svc = _services.getService(servstr); @@ -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 cd4304f5405..88d17a93b44 100644 --- a/logd/src/logd/service.cpp +++ b/logd/src/logd/service.cpp @@ -1,25 +1,26 @@ // 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 <time.h> -#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"); -LOG_RCSID("$Id$"); -#include "service.h" namespace logdemon { unsigned long Component::defFwd = (unsigned long)-1; +Component::Component(const std::string & servicename, const std::string & name) + : _isforwarding(defFwd), _lastseen(0.0), _lastpid(0), + _myservice(servicename), _myname(name), + _logctlname(name.substr(name.find('.'))) +{ + assert(ns_log::Logger::NUM_LOGLEVELS < 32); +} + +Component::~Component() = default; void Component::doLogAtAll(LogLevel level) @@ -27,16 +28,16 @@ Component::doLogAtAll(LogLevel level) using ns_log::ControlFile; char lcfn[FILENAME_MAX]; - if (! ControlFile::makeName(_myservice, lcfn, FILENAME_MAX)) { - LOG(debug, "no logcontrol file for service '%s'", _myservice); + if (! ControlFile::makeName(_myservice.c_str(), lcfn, FILENAME_MAX)) { + LOG(debug, "no logcontrol file for service '%s'", _myservice.c_str()); return; } 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); + LOG(debug, "exception changing logcontrol for %s", _myservice.c_str()); } } @@ -46,94 +47,96 @@ Component::dontLogAtAll(LogLevel level) using ns_log::ControlFile; char lcfn[FILENAME_MAX]; - if (! ControlFile::makeName(_myservice, lcfn, FILENAME_MAX)) { - LOG(debug, "no logcontrol file for service '%s'", _myservice); + if (! ControlFile::makeName(_myservice.c_str(), lcfn, FILENAME_MAX)) { + LOG(debug, "no logcontrol file for service '%s'", _myservice.c_str()); return; } 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); + LOG(debug, "exception changing logcontrol for %s", _myservice.c_str()); } } bool -Component::shouldLogAtAll(LogLevel level) +Component::shouldLogAtAll(LogLevel level) const { using ns_log::ControlFile; char lcfn[FILENAME_MAX]; - if (! ControlFile::makeName(_myservice, lcfn, FILENAME_MAX)) { - LOG(spam, "no logcontrol file for service '%s'", _myservice); + if (! ControlFile::makeName(_myservice.c_str(), lcfn, FILENAME_MAX)) { + LOG(spam, "no logcontrol file for service '%s'", _myservice.c_str()); return true; } try { ControlFile foo(lcfn, ControlFile::READWRITE); - unsigned int *lstring = foo.getLevels(_logctlname); - if (lstring[level] == CHARS_TO_UINT(' ', ' ', 'O', 'N')) - return true; - else - return false; + 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); + LOG(debug, "exception checking logcontrol for %s", _myservice.c_str()); } return true; } - -Service::~Service() +Service::Service(const std::string & name) + : _myname(name), + _components() { - CompIter it = _components.iterator(); - while (it.valid()) { - delete it.value(); - it.next(); +} + +Service::~Service() = default; + +Component * +Service::getComponent(const std::string & comp) { + auto found = _components.find(comp); + if (found == _components.end()) { + _components[comp] = std::make_unique<Component>(_myname, comp); + 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 std::string & serv) { + auto found = _services.find(serv); + if (found == _services.end()) { + _services[serv] = std::make_unique<Service>(serv); + found = _services.find(serv); } + return found->second.get(); } +Services::Services() = default; +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(); } } - -} // namespace +} diff --git a/logd/src/logd/service.h b/logd/src/logd/service.h index 09b4ca3fa4b..65f580ee54e 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; + std::string _myservice; + std::string _myname; + std::string _logctlname; static unsigned long defFwd; public: @@ -29,67 +25,40 @@ 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 != NULL) { - strcpy(_logctlname, withoutprefix); - } else { - strcpy(_logctlname, ""); - } - } - ~Component() { free(_myname); free(_logctlname); } + bool shouldLogAtAll(LogLevel level) const; + Component(const std::string & servicename, const std::string & 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; - 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(NULL) {} + using ComponentMap = std::unordered_map<std::string, std::unique_ptr<Component>>; + Service(const Service& other) = delete; + Service& operator= (const Service& other) = delete; + Service(const std::string & name); ~Service(); + Component *getComponent(const std::string & comp); + const ComponentMap & components() const { return _components; } +private: + std::string _myname; + ComponentMap _components; }; -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(NULL) {} + std::unordered_map<std::string, std::unique_ptr<Service>> _services; + Service *getService(const std::string & serv); + 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 2adc1cbbdbb..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> @@ -41,7 +41,7 @@ void snooze(const struct timeval &start) tsp.tv_sec = (wait_usecs / 1000000); tsp.tv_nsec = (wait_usecs % 1000000) * 1000; - if (nanosleep(&tsp, NULL) != 0 && errno != EINTR) { + if (nanosleep(&tsp, nullptr) != 0 && errno != EINTR) { LOG(error, "nanosleep %ld s %ld ns failed: %s", (long)tsp.tv_sec, (long)tsp.tv_nsec, strerror(errno)); throw SomethingBad("nanosleep failed"); @@ -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 == NULL) { - 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)); } } @@ -174,9 +166,8 @@ Watcher::watchfile() struct donecache already; char *target = getenv("VESPA_LOG_TARGET"); - if (target == NULL || strncmp(target, "file:", 5) != 0) { - LOG(error, "expected VESPA_LOG_TARGET (%s) to be a file: target", - target); + if (target == nullptr || strncmp(target, "file:", 5) != 0) { + 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,18 +234,17 @@ 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 == NULL && 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 != NULL && elapsed(tickStart) < 1) { + while (nnl != nullptr && elapsed(tickStart) < 1) { ++nnl; _forwarder.forwardLine(l, nnl); ssize_t wsize = nnl - l; @@ -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"); } } @@ -276,15 +262,13 @@ Watcher::watchfile() already.st_dev = sb.st_dev; already.st_ino = sb.st_ino; - time_t now = time(NULL); + time_t now = time(nullptr); bool wantrotate = (now > created + _confsubscriber.getRotateAge()) || (sb.st_size > _confsubscriber.getRotateSize()); 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; } @@ -388,7 +369,7 @@ Watcher::removeOldLogs(const char *prefix) myglob.gl_pathc = 0; myglob.gl_offs = 0; myglob.gl_flags = 0; - myglob.gl_pathv = NULL; + myglob.gl_pathv = nullptr; off_t totalsize = 0; @@ -404,10 +385,10 @@ Watcher::removeOldLogs(const char *prefix) } if (S_ISREG(sb.st_mode)) { if (sb.st_mtime + - _confsubscriber.getRemoveAge() * 86400 < time(NULL)) + _confsubscriber.getRemoveAge() * 86400 < time(nullptr)) { LOG(info, "removing %s, too old (%f days)", fname, - (double)(time(NULL)-sb.st_mtime)/86400.0); + (double)(time(nullptr)-sb.st_mtime)/86400.0); if (unlink(fname) != 0) { LOG(warning, "cannot remove %s: %s", @@ -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 29523181303..bcac6046b6f 100644 --- a/logd/src/logd/watch.h +++ b/logd/src/logd/watch.h @@ -1,18 +1,25 @@ // 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; +class ConfSub; + class Watcher { private: - char *_buffer; - ConfSub& _confsubscriber; - Forwarder& _forwarder; - int _wfd; - - Watcher(const Watcher& other); - Watcher& operator=(const Watcher& other); + 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; Watcher(ConfSub &cfs, Forwarder &fw); ~Watcher(); @@ -20,4 +27,4 @@ public: void removeOldLogs(const char *prefix); }; -} // namespace +} diff --git a/logd/src/tests/forward/forward.cpp b/logd/src/tests/forward/forward.cpp index db0a4e5de69..a2f1a8c8b7a 100644 --- a/logd/src/tests/forward/forward.cpp +++ b/logd/src/tests/forward/forward.cpp @@ -3,6 +3,7 @@ #include <vespa/vespalib/testkit/testapp.h> #include <vespa/vespalib/metrics/dummy_metrics_manager.h> #include <logd/forward.h> +#include <logd/metrics.h> #include <sstream> #include <fcntl.h> #include <unistd.h> |