/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <folly/Conv.h> #include <folly/Portability.h> #include <folly/lang/Exception.h> #include <folly/lang/TypeInfo.h> /* * This file contains functions for converting arbitrary objects to strings for * logging purposes. * * - folly::logging::objectToString(object) --> std::string * - folly::logging::appendToString(result, object) * - folly::logging::appendToString(result, object1, object2, ...) * * These functions behave somewhat similarly to `folly::to<std::string>(object)` * but always produce a result, rather than failing to compile for objects that * do not have a predefined mechanism for converting them to a string. * * If a `toAppend(std::string&, const Arg& object)` function has been defined * for the given object type this will be used to format the object. (This is * the same mechanism used by `folly::to<std::string>()`.) If a `toAppend()` * function is not defined these functions fall back to emitting a string that * includes the object type name, the object size, and a hex-dump representation * of the object contents. * * When invoked with multiple arguments `appendToString()` puts ", " between * each argument in the output. This also differs from * `folly::to<std::string>()`, which puts no extra output between arguments. */ namespace folly { namespace logging { namespace detail { void appendRawObjectInfo( std::string& result, const std::type_info* type, const uint8_t* data, size_t length); } // namespace detail /** * Append raw information about an object to a string. * * This is used as a fallback for objects that we do not otherwise know how to * print. This emits: * - The object type name (if RTTI is supported) * - The object size * - A hexdump of the object contents. * * e.g. * [MyStruct of size 4: 37 6f af 2a] * [AnotherClass of size 8: f9 48 78 85 56 54 8f 54] */ template <typename Arg> inline void appendRawObjectInfo(std::string& str, const Arg* arg) { … } /* * Helper functions for object to string conversion. * These are in a detail namespace so that we can include a using directive in * order to do proper argument-dependent lookup of the correct toAppend() * function to use. */ namespace detail { /* using override */ toAppend; template <typename Arg> auto appendObjectToString(std::string& str, const Arg* arg, int) -> decltype(toAppend(std::declval<Arg>(), std::declval<std::string*>()), std::declval<void>()) { … } template <typename Arg> inline void appendObjectToString(std::string& str, const Arg* arg, long) { … } } // namespace detail /** * Convert an arbitrary object to a string for logging purposes. */ template <typename Arg> std::string objectToString(const Arg& arg) { … } /** * Append an arbitrary object to a string for logging purposes. */ template <typename Arg> void appendToString(std::string& result, const Arg& arg) { … } /** * Append an arbitrary group of objects to a string for logging purposes. * * This function outputs a comma and space (", ") between each pair of objects. */ template <typename Arg1, typename... Args> void appendToString( std::string& result, const Arg1& arg1, const Args&... remainder) { … } /** * Overload when there are no objects to append. */ template <typename Arg = void> void appendToString(std::string& /*result*/) { … } } // namespace logging } // namespace folly