diff --git a/example/example.cpp b/example/example.cpp index 6a9b1bac..23afa6d5 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -404,5 +404,5 @@ void attribute_example() { std::string logfmt_pattern = "time=%Y-%m-%dT%H:%M:%S.%f%z, name=%n, level=%^%l%$, process=%P, thread=%t, message=\"%v\", "; logfmt_logger->set_pattern(logfmt_pattern); - logfmt_logger->log(spdlog::level::info, "logfmt structured logging", {{"key1", "value1"}, {"key2", "value2"}}); + logfmt_logger->log(spdlog::level::info, "logfmt structured logging", {{"key\n1", "value\n1"}, {"key\r\n2", "value\r\n2"}}); } \ No newline at end of file diff --git a/include/spdlog/details/attr_composer.h b/include/spdlog/details/attr_composer.h new file mode 100644 index 00000000..4d7ab50e --- /dev/null +++ b/include/spdlog/details/attr_composer.h @@ -0,0 +1,75 @@ +#pragma once + +#include + +namespace spdlog { +namespace details { + +inline void scramble(std::string& dst, std::string_view s) +{ + if (s.empty()) + return; + + auto start = s.data(); + auto const end = s.data() + s.size(); + auto cursor = start; + + dst.reserve(dst.size() + s.size()); + + auto replace = [&](std::string_view with) { + dst.append(start, size_t(cursor - start)); + ++cursor; + start = cursor; + dst.append(with); + }; + + while (cursor != end) { + auto c = static_cast(*cursor); + + switch (c) { + case '\b': + replace("\\b"); + break; + case '\f': + replace("\\f"); + break; + case '\n': + replace("\\n"); + break; + case '\r': + replace("\\r"); + break; + case '\t': + replace("\\t"); + break; + case '\\': + replace("\\\\"); + break; + case '"': + replace("\\\""); + break; + default: + if (c <= '\x0f') { + char buf[] = "\\u0000"; + buf[5] += c; + if (c >= '\x0a') + buf[5] += 'a' - ':'; + replace(buf); + } + else if (c <= '\x1f' || c == 0x7f) { + char buf[] = "\\u0010"; + buf[5] += c - 16; + if (c >= '\x1a') + buf[5] += 'a' - ':'; + replace(buf); + } + else + ++cursor; + } + } + if (cursor != start) + dst.append({start, size_t(cursor - start)}); +} + +} +} \ No newline at end of file diff --git a/include/spdlog/details/log_attr.h b/include/spdlog/details/log_attr.h index 757661b3..09da714d 100644 --- a/include/spdlog/details/log_attr.h +++ b/include/spdlog/details/log_attr.h @@ -3,6 +3,7 @@ #include #include #include +#include "attr_composer.h" namespace spdlog { namespace details { @@ -12,15 +13,15 @@ namespace details { struct attr { - std::string_view key; - std::string_view value; + std::string key; + std::string value; public: attr(std::initializer_list l) { if (l.size() != 2) return; // throw exception if not kv pair? - key = *l.begin(); - value = *(l.begin()+1); + scramble(key, *l.begin()); + scramble(value, *(l.begin()+1)); } attr(std::string_view k, bool v)