blob: 9e38f429974a180eb854af12dc88e00f4c0779f1 [file]
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_LOGGING_LOGDECORATORS_HPP
#define SHARE_LOGGING_LOGDECORATORS_HPP
#include "utilities/globalDefinitions.hpp"
#include "logging/logSelection.hpp"
class outputStream;
// The list of available decorators:
// time - Current time and date in ISO-8601 format
// uptime - Time since the start of the JVM in seconds and milliseconds (e.g., 6.567s)
// timemillis - The same value as generated by System.currentTimeMillis()
// uptimemillis - Milliseconds since the JVM started
// timenanos - The same value as generated by System.nanoTime()
// uptimenanos - Nanoseconds since the JVM started
// hostname - The hostname
// pid - The process identifier
// tid - The thread identifier
// level - The level associated with the log message
// tags - The tag-set associated with the log message
#define DECORATOR_LIST \
DECORATOR(time, t) \
DECORATOR(utctime, utc) \
DECORATOR(uptime, u) \
DECORATOR(timemillis, tm) \
DECORATOR(uptimemillis, um) \
DECORATOR(timenanos, tn) \
DECORATOR(uptimenanos, un) \
DECORATOR(hostname, hn) \
DECORATOR(pid, p) \
DECORATOR(tid, ti) \
DECORATOR(level, l) \
DECORATOR(tags, tg)
// LogDecorators represents a selection of decorators that should be prepended to
// each log message for a given output. Decorators are always prepended in the order
// declared above. For example, logging with 'uptime, level, tags' decorators results in:
// [0,943s][info ][logging] message.
class LogDecorators {
friend class TestLogDecorators;
public:
enum Decorator {
#define DECORATOR(name, abbr) name##_decorator,
DECORATOR_LIST
#undef DECORATOR
Count,
Invalid
};
class DefaultUndecoratedSelection {
friend class TestLogDecorators;
LogSelection _selection;
DefaultUndecoratedSelection() : _selection(LogSelection::Invalid) {}
DefaultUndecoratedSelection(LogLevelType level, LogTagType t0, LogTagType t1, LogTagType t2,
LogTagType t3, LogTagType t4) : _selection(LogSelection::Invalid) {
LogTagType tag_arr[LogTag::MaxTags] = { t0, t1, t2, t3, t4 };
_selection = LogSelection(tag_arr, false, level);
}
public:
template <LogLevelType Level, LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,
LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
static DefaultUndecoratedSelection make() {
STATIC_ASSERT(GuardTag == LogTag::__NO_TAG);
return DefaultUndecoratedSelection(Level, T0, T1, T2, T3, T4);
}
const LogSelection& selection() const { return _selection; }
};
private:
uint _decorators;
static const char* _name[][2];
static const uint defaultsMask = (1 << uptime_decorator) | (1 << level_decorator) | (1 << tags_decorator);
static const LogDecorators::DefaultUndecoratedSelection default_decorators[];
static const size_t number_of_default_decorators;
static uint mask(LogDecorators::Decorator decorator) {
return 1 << decorator;
}
public:
static const LogDecorators None;
static const LogDecorators All;
constexpr LogDecorators(uint mask) : _decorators(mask) {}
LogDecorators() : _decorators(defaultsMask) {}
void clear() {
_decorators = 0;
}
static const char* name(LogDecorators::Decorator decorator) {
return _name[decorator][0];
}
static const char* abbreviation(LogDecorators::Decorator decorator) {
return _name[decorator][1];
}
template<typename... Decorators>
static uint mask_from_decorators(LogDecorators::Decorator first, Decorators... rest) {
uint bitmask = 0;
LogDecorators::Decorator decorators[1 + sizeof...(rest)] = { first, rest... };
for (const LogDecorators::Decorator decorator : decorators) {
bitmask |= mask(decorator);
}
return bitmask;
}
// Check if we have some default decorators for a given LogSelection. If that is the case,
// the output parameter mask will contain the defaults-specified decorators mask
static bool has_disabled_default_decorators(const LogSelection& selection, const DefaultUndecoratedSelection* defaults = default_decorators, size_t defaults_count = number_of_default_decorators);
static LogDecorators::Decorator from_string(const char* str);
void combine_with(const LogDecorators &source) {
_decorators |= source._decorators;
}
bool is_empty() const {
return _decorators == 0;
}
bool is_decorator(LogDecorators::Decorator decorator) const {
return (_decorators & mask(decorator)) != 0;
}
bool parse(const char* decorator_args, outputStream* errstream = nullptr);
};
#endif // SHARE_LOGGING_LOGDECORATORS_HPP