...
 
Commits (4)
......@@ -4,8 +4,10 @@
#ifndef DUNE_LOGGING_FILESINKS_HH
#define DUNE_LOGGING_FILESINKS_HH
#include <iterator>
#include <fstream>
#include <string>
#include <string_view>
#include <fmt/posix.h>
#include <dune/logging/patternformatsink.hh>
......@@ -44,23 +46,23 @@ namespace Dune::Logging {
LogLevel level,
std::size_t widest_logger,
const std::string& file_name,
std::ios_base::openmode mode
const std::string& mode
)
: PatternFormatSink(name,level,widest_logger)
, _file_name(file_name)
, _file(file_name,mode)
{}
void process(const LogMessage& msg)
void process(const LogMessage& msg) override
{
PatternFormatSink::Arguments args(msg,*this);
fmt::vprint(_file, fmt::to_string_view(pattern()), args);
_file.vprint(fmt::to_string_view(pattern()), args);
}
private:
std::string _file_name;
std::ofstream _file;
fmt::buffered_file _file;
};
......
......@@ -57,6 +57,12 @@ namespace Dune::Logging {
return { string, sizeof...(chars) };
}
constexpr friend fmt::basic_string_view<char_type> to_string_view(format_string s)
{
return { s };
}
};
//! A special string_view that lets us ensure that users always use the _fmt literal for format strings.
......@@ -197,13 +203,29 @@ namespace Dune::Logging {
namespace fmt {
template <typename Factory, bool cached>
struct formatter<Dune::Logging::LazyFormatArgument<Factory,cached>>
: public formatter<std::decay_t<decltype(std::declval<Factory>()())>>
template <typename Factory, bool cached, typename Char>
struct formatter<Dune::Logging::LazyFormatArgument<Factory,cached>,Char>
: public formatter<
std::conditional_t<
fmt::internal::is_string<
std::decay_t<decltype(std::declval<Factory>()())>
>::value,
fmt::basic_string_view<Char>,
std::decay_t<decltype(std::declval<Factory>()())>
>,
Char
>
{
using Arg = Dune::Logging::LazyFormatArgument<Factory,cached>;
using Base = formatter<std::decay_t<decltype(std::declval<Arg>()())>>;
using Arg = Dune::Logging::LazyFormatArgument<Factory,cached>;
using Result = std::decay_t<decltype(std::declval<Factory>()())>;
using Base = formatter<
std::conditional_t<
fmt::internal::is_string<Result>::value,
fmt::basic_string_view<Char>,
Result
>,
Char>;
// we just inherit the parsing from the original formatter
......
......@@ -38,21 +38,23 @@ namespace Dune::Logging {
const ParameterTree& params
)
{
using namespace std::literals;
if (not params.hasKey("file"))
DUNE_THROW(LoggingError,"You must specify an output file name for file sink: " << name);
auto file_name = params["file"];
if (file_name.empty())
DUNE_THROW(LoggingError,"You must specify an output file name for file sink: " << name);
auto mode = std::ios::trunc;
auto mode = "we"s;
if (params.hasKey("mode"))
{
auto mode_name = params["mode"];
if (mode_name == "truncate")
mode = std::ios::trunc;
mode = "we";
else if (mode_name == "append")
mode = std::ios::ate;
mode = "ae";
else
DUNE_THROW(LoggingError,"Unknown file open mode " << mode_name << ": " << name);
}
......@@ -89,21 +91,23 @@ namespace Dune::Logging {
const ParameterTree& params
) -> std::shared_ptr<Sink>
{
using namespace std::literals;
if (not params.hasKey("file"))
DUNE_THROW(LoggingError,"You must specify an output file name for file sink: " << name);
auto file_name = params["file"];
if (file_name.empty())
DUNE_THROW(LoggingError,"You must specify an output file name for file sink: " << name);
auto mode = std::ios::trunc;
auto mode = "we"s;
if (params.hasKey("mode"))
{
auto mode_name = params["mode"];
if (mode_name == "truncate")
mode = std::ios::trunc;
mode = "we"s;
else if (mode_name == "append")
mode = std::ios::ate;
mode = "ae"s;
else
DUNE_THROW(LoggingError,"Unknown file open mode " << mode_name << ": " << name);
}
......
......@@ -96,12 +96,12 @@ namespace fmt {
// make it possible to format a LogLevel in a log message
template <>
struct formatter<Dune::Logging::LogLevel>
: public formatter<std::string_view>
template <typename Char>
struct formatter<Dune::Logging::LogLevel,Char>
: public formatter<fmt::basic_string_view<Char>,Char>
{
using Base = formatter<std::string_view>;
using Base = formatter<fmt::basic_string_view<Char>,Char>;
// we just inherit the parsing from the original formatter
......
......@@ -83,11 +83,11 @@ namespace Dune::Logging {
* This class provides opaque storage for the format arguments required by
* the current pattern. An object of this type should be constructed in
* derived classes before formatting the pattern. This type implicitly casts
* to `fmt::format_args`, which can be used passed to the {fmt} formatting
* to `fmt::format_args`, which can be passed to the {fmt} formatting
* functions.
*
* \note You **must** create a named object of this type; trying to feed a
* temporary object to {}fmt} will cause a compiler error.
* temporary object to {fmt} will cause a compiler error.
*/
class Arguments
{
......