logging_info.cc 6.63 KB
Newer Older
1
// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
2
//
3 4 5
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6

7
#include <config.h>
8 9
#include <process/logging_info.h>
#include <process/daemon.h>
10 11 12
#include <log/logger_name.h>

using namespace isc::log;
13
using namespace isc::data;
14 15

namespace isc {
16
namespace process {
17 18 19 20 21

bool
LoggingDestination::equals(const LoggingDestination& other) const {
    return (output_ == other.output_ &&
            maxver_ == other.maxver_ &&
22 23
            maxsize_ == other.maxsize_ &&
            flush_ == other.flush_);
24 25
}

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
ElementPtr
LoggingDestination::toElement() const {
    ElementPtr result = Element::createMap();

    // Set output
    result->set("output", Element::create(output_));
    // Set maxver
    result->set("maxver", Element::create(maxver_));
    // Set maxsize
    result->set("maxsize", Element::create(static_cast<long long>(maxsize_)));
    // Set flush
    result->set("flush", Element::create(flush_));

    return(result);
}

42 43 44 45
LoggingInfo::LoggingInfo()
    : name_("kea"), severity_(isc::log::INFO), debuglevel_(0) {
    // If configuration Manager is in the verbose mode, we need to modify the
    // default settings.
46
    if (Daemon::getVerbose()) {
47 48 49 50 51 52
        severity_ = isc::log::DEBUG;
        debuglevel_ = 99;
    }

    // If the process has set the non-empty name for the default logger,
    // let's use this name.
53 54 55
    std::string default_logger = Daemon::getDefaultLoggerName();
    if (!default_logger.empty()) {
        name_ = default_logger;
56 57 58 59 60 61 62 63 64
    }

    // Add a default logging destination in case use hasn't provided a
    // logger specification.
    LoggingDestination dest;
    dest.output_ = "stdout";
    destinations_.push_back(dest);
}

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
bool
LoggingInfo::equals(const LoggingInfo& other) const {
    // If number of destinations aren't equal, the objects are not equal.
    if (destinations_.size() != other.destinations_.size()) {
        return (false);
    }
    // If there is the same number of logging destinations verify that the
    // destinations are equal. The order doesn't matter to we don't expect
    // that they are at the same index of the vectors.
    for (std::vector<LoggingDestination>::const_iterator
             it_this = destinations_.begin();
         it_this != destinations_.end();
         ++it_this) {
        bool match = false;
        for (std::vector<LoggingDestination>::const_iterator
                 it_other = other.destinations_.begin();
             it_other != other.destinations_.end();
             ++it_other) {
            if (it_this->equals(*it_other)) {
                match = true;
                break;
            }
        }
        if (!match) {
            return (false);
        }
    }

    // Logging destinations are equal. Check the rest of the parameters for
    // equality.
    return (name_ == other.name_ &&
            severity_ == other.severity_ &&
            debuglevel_ == other.debuglevel_);
}

100 101 102 103 104 105 106 107 108
LoggerSpecification
LoggingInfo::toSpec() const {
    static const std::string STDOUT = "stdout";
    static const std::string STDERR = "stderr";
    static const std::string SYSLOG = "syslog";
    static const std::string SYSLOG_COLON = "syslog:";

    LoggerSpecification spec(name_, severity_, debuglevel_);

Andrei Pavel's avatar
Andrei Pavel committed
109
    // Go over logger destinations and create output options accordingly.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
    for (std::vector<LoggingDestination>::const_iterator dest =
             destinations_.begin(); dest != destinations_.end(); ++dest) {

        OutputOption option;
        // Set up output option according to destination specification
        if (dest->output_ == STDOUT) {
            option.destination = OutputOption::DEST_CONSOLE;
            option.stream = OutputOption::STR_STDOUT;

        } else if (dest->output_ == STDERR) {
            option.destination = OutputOption::DEST_CONSOLE;
            option.stream = OutputOption::STR_STDERR;

        } else if (dest->output_ == SYSLOG) {
            option.destination = OutputOption::DEST_SYSLOG;
            // Use default specified in OutputOption constructor for the
            // syslog destination

        } else if (dest->output_.find(SYSLOG_COLON) == 0) {
            option.destination = OutputOption::DEST_SYSLOG;
            // Must take account of the string actually being "syslog:"
            if (dest->output_ == SYSLOG_COLON) {
                // The expected syntax is syslog:facility. User skipped
                // the logging name, so we'll just use the default ("kea")
                option.facility = isc::log::getDefaultRootLoggerName();

            } else {
                // Everything else in the string is the facility name
                option.facility = dest->output_.substr(SYSLOG_COLON.size());
            }

        } else {
Francis Dupont's avatar
Francis Dupont committed
142
            // Not a recognized destination, assume a file.
143 144
            option.destination = OutputOption::DEST_FILE;
            option.filename = dest->output_;
145 146
            option.maxsize = dest->maxsize_;
            option.maxver = dest->maxver_;
147 148
        }

149
        // Copy the immediate flush flag
150
        option.flush = dest->flush_;
151

152 153 154 155 156 157 158
        // ... and set the destination
        spec.addOutputOption(option);
    }

    return (spec);
}

159 160 161
ElementPtr
LoggingInfo::toElement() const {
    ElementPtr result = Element::createMap();
162 163
    // Set user context
    contextToElement(result);
164 165
    // Set name
    result->set("name", Element::create(name_));
166 167 168 169 170 171 172 173 174
    // Set output_options if not empty
    if (!destinations_.empty()) {
        ElementPtr options = Element::createList();
        for (std::vector<LoggingDestination>::const_iterator dest =
                 destinations_.cbegin();
             dest != destinations_.cend(); ++dest) {
            options->add(dest->toElement());
        }
        result->set("output_options", options);
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
    }
    // Set severity
    std::string severity;
    switch (severity_) {
    case isc::log::DEBUG:
        severity = "DEBUG";
        break;
    case isc::log::INFO:
        severity = "INFO";
        break;
    case isc::log::WARN:
        severity = "WARN";
        break;
    case isc::log::ERROR:
        severity = "ERROR";
        break;
    case isc::log::FATAL:
        severity = "FATAL";
        break;
    case isc::log::NONE:
        severity = "NONE";
        break;
    default:
        isc_throw(ToElementError, "illegal severity: " << severity_);
        break;
    }
    result->set("severity", Element::create(severity));
    // Set debug level
    result->set("debuglevel", Element::create(debuglevel_));
    return (result);
}

207 208
} // end of namespace isc::dhcp
} // end of namespace isc