Project Icon

BqLog

多平台多语言支持的高性能日志系统

BqLog是一款高性能轻量级日志系统,支持多个主流操作系统平台和编程语言。该系统以低内存占用和高压缩实时日志格式为特色,可无缝集成到游戏引擎中。BqLog提供异步日志、崩溃恢复和自定义参数类型等高级功能,是一个全面而易用的日志解决方案。适用于需要高效日志记录的各类应用开发。

BqLog(扁鹊日志)(V 1.4.0)

中文文档
BqLog is a lightweight, high-performance logging system used in projects such as "Honor of Kings," and it has been successfully deployed and is running smoothly.

Supported Platforms

  • Windows 64 bit
  • MacOS
  • Linux
  • iOS
  • Android(X86_64, arm64-v8a、armeabi-v7a)

Supported Languages

  • C++
  • Java
  • Kotlin
  • C#

Features

  • Compared to existing open-source logging libraries, BqLog offers significant performance advantages (see Benchmark). It is not only suitable for servers and clients but also highly compatible with mobile devices.
  • With low memory consumption, in the Benchmark case of 10 threads and 20,000,000 log entries, BqLog itself consumes less than 1 MB of memory.
  • Provides a high-performance, high-compression real-time log format
  • Can be used normally in game engines (Unity, Unreal), with support for common types provided for Unreal.
  • Supports UTF-8, UTF-16, UTF-32 characters and strings, as well as common parameter types like bool, float, double, and various lengths and types of integers
  • Supports C++20 format specifications
  • Asynchronous logging supports crash review to avoid data loss (inspired by XLog)
  • Extremely small size, with the dynamic library being only about 200k after Android compilation
  • Does not generate additional heap allocations in Java and C#, avoiding constant new object creation during runtime
  • Only depends on the standard C language library and platform APIs, and can be compiled in Android's ANDROID_STL = none mode
  • Supports C++11 and later compilation standards, and can be compiled under strict requirements of -Wall -Wextra -pedantic -Werror
  • Compilation module is based on CMake and provides compilation scripts for different platforms, making it easy to use
  • Supports custom parameter types
  • Very friendly to code suggestions

Menu

Integrating BqLog into Your Project
Simple Demo
Architecture Overview
Main Process API Usage Instructions
    1-Creating a Log Object
    2-Retrieving a Log Object
    3-Logging Messages
    4-Other APIs
Synchronous and Asynchronous Logging
    1. Thread safety of asynchronous logging
Introduction to Appenders
    1. ConsoleAppender
    2. TextFileAppender
    3. CompressedFileAppender(Highly Recommended)
    4. RawFileAppender
Configuration Instructions
    1. Complete Example
    2. Detailed Explanation
Offline Decoding of Binary Format Appenders
Build Instructions
    1. Library Build
    2. Demo Build and Run
    3. Automated Test Run Instructions
    4. Benchmark Run Instructions
Advanced Usage Topics
    1. No Heap Allocation
    2. Log Objects with Category Support
    3. Data Protection on Program Abnormal Exit
    4. About NDK and ANDROID_STL = none
    5. Custom Parameter Types
    6. Using BqLog in Unreal Engine
Benchmark
    1. Benchmark Description
    2. BqLog C++ Benchmark Code
    3. BqLog Java Benchmark Code
    4. Log4j Benchmark Code
    5. Benchmark Results

Integrating BqLog into Your Project

BqLog can be integrated into your project in various forms. For C++, it supports dynamic libraries, static libraries, and source files. For Java and C#, it supports dynamic libraries with wrapper source code. Below are the methods to include BqLog:

C++ (Dynamic Library)

The code repository includes precompiled dynamic library files located in /dist/dynamic_lib/. To integrate BqLog into your project using the library files, you need to do the following:

  • Select the dynamic library file corresponding to your platform and add it to your project's build system.
  • Copy the /dist/dynamic_lib/include directory into your project and add it to the include directory list. (If you are using XCode's .framework library, you can skip this step as the .framework file already includes the header files).

C++ (Static Library)

The code repository includes precompiled static library files located in /dist/static_lib/. To integrate BqLog into your project using the library files, you need to do the following:

  • Select the static library file corresponding to your platform and add it to your project's build system.
  • Copy the /dist/static_lib/include directory into your project and add it to the include directory list. (If you are using XCode's .framework library, you can skip this step as the .framework file already includes the header files).

C++ (Source Code)

BqLog also supports direct inclusion of source code into your project for compilation. To integrate BqLog using the source code, follow these steps:

  • Copy the /src directory into your project as a source code reference.
  • Copy the /include directory into your project and add it to the include directory list.
  • If compiling the Windows version in Visual Studio, add /Zc:__cplusplus to the compilation options to ensure the current C++ compiler standard support is correctly determined.
  • If using the source code in Android's NDK, please refer to 4. About NDK and ANDROID_STL = none for important considerations.

C#

In C#, BqLog can be used via a native dynamic library and a C# Wrapper, supporting Mono, Microsoft CLR, and Unity engines. Unity is compatible with both Mono and IL2CPP modes. To use BqLog in C#, follow these steps:

  • Select the dynamic library file corresponding to your platform from /dist/dynamic_lib/ and add it to your project (for Unity, refer to Unity Import and configure plug-ins).
  • Copy the source code files from /wrapper/csharp/src into your project.

Java

In Java, BqLog can be used via a native dynamic library and a Java Wrapper, supporting common JVM environments and Android. To integrate BqLog into a JVM, follow these steps:

  • Select the dynamic library file corresponding to your platform from /dist/dynamic_lib/ and add it to your project.
  • Copy the source code files from /wrapper/java/src into your project.
  • (Optional) Copy the /dist/dynamic_lib/include directory into your project and add it to the include directory list if you intend to call BqLog from the NDK.



Simple Demo

The following code will output over 1000 logs to your console (or ADB Logcat if on Android)

C++

#if defined(WIN32)
#include <windows.h>
#endif
#include <string>
#include <bq_log/bq_log.h>
int main()
{
#if defined(WIN32)
    // Switch Windows command line to UTF-8 because BqLog outputs all final text in UTF-8 encoding to avoid display issues
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);
#endif
    // This string is the log configuration. Here it configures a logger with one appender (output target) named appender_0, which outputs to the console.
    std::string config = R"(
            # This appender's output target is the console
            appenders_config.appender_0.type=console           
            # This appender uses local time for timestamps
            appenders_config.appender_0.time_zone=default local time   
            # This appender outputs logs of these 6 levels (no spaces in between)
            appenders_config.appender_0.levels=[verbose,debug,info,warning,error,fatal] 
        )";
    bq::log log = bq::log::create_log("my_first_log", config);   // Create a log object using the config
    for(int i = 0; i < 1024; ++i)
    {
        log.info("This is an info test log, the format string is UTF-8, param int:{}, param bool :{}, param string8:{}, param string16:{}, param string32:{}, param float:{}", i, true, "utf8-string", u"utf16-string", U"utf32-string", 4.3464f);  
    }
    log.error(U"This is an error test log, the format string is UTF-32");  
    bq::log::force_flush_all_logs();   // BqLog defaults to asynchronous output. To ensure logs are visible before program exit, force flush to sync output once.
    return 0;
}

C#

using System.Text;
using System;

public class demo_main {

    public static void Main(string[] args) {
        Console.OutputEncoding = Encoding.UTF8;
        Console.InputEncoding = Encoding.UTF8;
        string config = @"
            # This appender's output target is the console
            appenders_config.appender_0.type=console           
            # This appender uses local time for timestamps
            ppenders_config.appender_0.time_zone=default local time   
            # This appender outputs logs of these 6 levels (no spaces in between)
            appenders_config.appender_0.levels=[verbose,debug,info,warning,error,fatal] 
        ";
        bq.log log = bq.log.create_log("my_first_log", config);   // Create a log object using the config
        for (int i = 0; i < 1024; ++i)
        {
            log.info("This is an info test log, the format string is UTF-16, param int:{}, param bool :{}, param string:{}, param float:{}", i, true, "String Text", 4.3464f);
        }


        bq.log.force_flush_all_logs();
        Console.ReadKey();
    }

}

Java#

public class demo_main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String config = """
            # This appender's output target is the console
            appenders_config.appender_0.type=console           
            # This appender uses local time for timestamps
            appenders_config.appender_0.time_zone=default local time   
            # This appender outputs logs of these 6 levels (no spaces in between)
            appenders_config.appender_0.levels=[verbose,debug,info,warning,error,fatal] 
        """;
        bq.log log = bq.log.create_log("my_first_log", config);   // Create a log object using the config
        for (int i = 0; i < 1024; ++i)
        {
            log.info("This is an info test log, the format string is UTF-16, param int:{}, param bool :{}, param string:{}, param float:{}", i, true, "String Text", 4.3464f);
        }
        bq.log.force_flush_all_logs();
    }
}



Architecture Overview

Basic Structure

The diagram above clearly illustrates the basic structure of BqLog. On the right side of the diagram is the internal implementation of the BqLog library, while on the left side is your program and code. Your program can call BqLog using the provided wrappers (object-oriented APIs for different languages). In the diagram, two Logs are created: one named "Log A" and the other named "Log B." Each Log is attached to one or more Appenders. An Appender can be understood as the output target of the log content. This can be the console (ADB Logcat logs for Android), text files, or even specialized formats like compressed log files or regular binary log format files.

Within the same process, wrappers for different languages can access the same Log object. For example, if a Log object named Log A is created in Java, it can also be accessed and used from the C++ side by the name Log A.
In extreme cases, such as a Unity-developed game running on the Android system, you might involve Java, Kotlin, C#, and C++ languages within the same app. They can all share the same Log object. You can create the Log on the Java side using create_log, and then access it in other languages using get_log_by_name.



Main Process API Usage Instructions

Note: The following APIs are declared in the bq::log (or bq.log) class. To save space, only the C++ APIs are listed. The APIs in Java and C# are identical and will not be repeated here.
In C++, bq::string is the UTF-8 string type in the BqLog library. You can also pass in c-style strings like char or std::string or std::string_view, which will be automatically and implicitly converted.

1. Creating a Log Object

A log object can be created using the create_log static function. Its declaration is as follows:

//C++ API
    /// <summary>
    /// Create a log object
    /// </summary>
    /// <param name="log_name">If the log name is an empty string, bqLog will automatically assign you a unique log name. If the log name already exists, it will return the previously existing log object and overwrite the previous configuration with the new config.</param>
    /// <param name="config_content">Log config string</param>
    /// <returns>A log object, if create failed, the is_valid() method of it will return false</returns>
    static log create_log(const bq::string& log_name, const bq::string& config_content);

The code creates a log object by passing in the name of the log object and a configuration string. The log configuration can be referenced in the Configuration Instructions. Here are a few key points to note:

  1. Regardless of whether it is C# or Java, the returned log object will never be null. However, due to configuration errors or other reasons, an invalid log object might be created. Therefore, you should use the is_valid() function to check the returned object. Performing operations on an invalid object may cause the program to crash.
  2. If an empty string is passed as the log name, bqLog will automatically generate a unique log name, such as "AutoBqLog_1."
  3. Calling create_log on an already existing log object with the same name will not create a new log object but will overwrite the previous configuration with the new one. However, some parameters cannot be modified in this process; see Configuration Instructions for details.
  4. Except when using in the NDK (refer to 4. About NDK and ANDROID_STL = none), you can initialize the log object directly in global or static variables using this API in other situations.

2. Retrieving a Log Object

If a log object has already been created elsewhere, you can obtain the created log object directly using the get_log_by_name function.

//C++ API
    /// <summary>
    /// Get a log object by it's name
    /// </summary>
    /// <param name="log_name">Name of the log object you want to find</param>
    /// <returns>A log object, if the log object with specific name was not found, the is_valid() method of it will return false</returns>
    static log get_log_by_name(const bq::string& log_name);

You can also use this function to initialize a log object in global variables or static functions. However, note that you must ensure the log object with the specified name already exists. Otherwise, the returned log object will be unusable, and its is_valid() method will return false.

3. Logging Messages

    ///Core log functions, there are 6 log levels:
    ///verbose, debug, info, warning, error, fatal
  
项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号