中文档
BqLog เป็นระบบบันทึกน้ำหนักเบาประสิทธิภาพสูงที่ใช้ในโปรเจ็กต์ต่างๆ เช่น "Honor of Kings" และปรับใช้ได้สำเร็จและทำงานได้อย่างราบรื่น
วินโดว์ 64 บิต
แมคโอเอส
ลินุกซ์
ไอโอเอส
ระบบปฏิบัติการ Android (X86_64, arm64-v8a, armeabi-v7a)
Unix (ผ่านการทดสอบบน FreeBSD)
ซี++
ชวา
คอตลิน
ค#
เมื่อเปรียบเทียบกับไลบรารีการบันทึกโอเพ่นซอร์สที่มีอยู่ BqLog มีข้อได้เปรียบด้านประสิทธิภาพที่สำคัญ (ดูเกณฑ์มาตรฐาน) ไม่เพียงแต่เหมาะสำหรับเซิร์ฟเวอร์และไคลเอนต์เท่านั้น แต่ยังเข้ากันได้กับอุปกรณ์มือถืออีกด้วย
ด้วยการใช้หน่วยความจำต่ำ ในกรณีเกณฑ์มาตรฐานที่มี 10 เธรดและรายการบันทึก 20,000,000 รายการ ตัว BqLog เองก็ใช้หน่วยความจำน้อยกว่า 1 MB
มอบรูปแบบบันทึกแบบเรียลไทม์ที่มีประสิทธิภาพสูงและมีการบีบอัดสูง
สามารถใช้งานได้ตามปกติในเอ็นจิ้นเกม ( Unity
, Unreal
) โดยรองรับประเภททั่วไปที่มีให้สำหรับ Unreal
รองรับอักขระและสตริง UTF-8
, UTF-16
, UTF-32
รวมถึงประเภทพารามิเตอร์ทั่วไป เช่น bool, float, double และความยาวและประเภทของจำนวนเต็มต่างๆ
รองรับ format specifications
C++20
การบันทึกแบบอะซิงโครนัสรองรับการตรวจสอบข้อขัดข้องเพื่อหลีกเลี่ยงการสูญเสียข้อมูล (ได้รับแรงบันดาลใจจาก XLog)
ขนาดเล็กมาก โดยไลบรารีไดนามิกมีขนาดเพียงประมาณ 200,000 หลังจากการคอมไพล์ Android
ไม่สร้างการจัดสรรฮีปเพิ่มเติมใน Java และ C# โดยหลีกเลี่ยงการสร้างออบเจ็กต์ใหม่อย่างต่อเนื่องระหว่างรันไทม์
ขึ้นอยู่กับไลบรารีภาษา C มาตรฐานและ API ของแพลตฟอร์มเท่านั้น และสามารถคอมไพล์ได้ในโหมด ANDROID_STL = none
ของ Android
รองรับมาตรฐานการคอมไพล์ C++11
และใหม่กว่า และสามารถคอมไพล์ได้ภายใต้ข้อกำหนดที่เข้มงวดของ -Wall -Wextra -pedantic -Werror
โมดูลการคอมไพล์ใช้ CMake
และจัดเตรียมสคริปต์การคอมไพล์สำหรับแพลตฟอร์มต่างๆ ทำให้ใช้งานง่าย
รองรับประเภทพารามิเตอร์ที่กำหนดเอง
เป็นมิตรกับคำแนะนำรหัสมาก
เหตุใด BqLog จึงเร็วมาก - รูปแบบบันทึกการบีบอัดเรียลไทม์ประสิทธิภาพสูง
เหตุใด BqLog จึงเร็วมาก - บัฟเฟอร์วงแหวนที่ทำงานพร้อมกันสูง
การรวม BqLog เข้ากับโครงการของคุณ
สาธิตง่ายๆ
ภาพรวมสถาปัตยกรรม
คำแนะนำการใช้งาน API กระบวนการหลัก
1- การสร้างวัตถุบันทึก
2- การดึงวัตถุบันทึก
3- การบันทึกข้อความ
4-API อื่นๆ
การบันทึกแบบซิงโครนัสและแบบอะซิงโครนัส
1. ความปลอดภัยของเธรดของการบันทึกแบบอะซิงโครนัส
ข้อมูลเบื้องต้นเกี่ยวกับภาคผนวก
1. คอนโซลผู้ผนวก
2. TextFileAppender
3. CompressedFileAppender (แนะนำเป็นอย่างยิ่ง)
4. RawFileAppender
คำแนะนำในการกำหนดค่า
1. ตัวอย่างที่สมบูรณ์
2. คำอธิบายโดยละเอียด
การถอดรหัสแบบออฟไลน์ของภาคผนวกรูปแบบไบนารี
คำแนะนำในการสร้าง
1. การสร้างห้องสมุด
2. สาธิตการสร้างและเรียกใช้
3. คำแนะนำการดำเนินการทดสอบอัตโนมัติ
4. คำแนะนำการเรียกใช้เกณฑ์มาตรฐาน
หัวข้อการใช้งานขั้นสูง
1. ไม่มีการจัดสรรฮีป
2. บันทึกวัตถุด้วยการสนับสนุนหมวดหมู่
3. การป้องกันข้อมูลเมื่อโปรแกรมออกผิดปกติ
4. เกี่ยวกับ NDK และ ANDROID_STL = ไม่มี
5. ประเภทพารามิเตอร์ที่กำหนดเอง
6. การใช้ BqLog ใน Unreal Engine
เกณฑ์มาตรฐาน
1. คำอธิบายเกณฑ์มาตรฐาน
2. รหัสเกณฑ์มาตรฐาน BqLog C++
3. รหัสเกณฑ์มาตรฐาน BqLog Java
4. รหัสเกณฑ์มาตรฐาน Log4j
5. ผลลัพธ์เกณฑ์มาตรฐาน
BqLog สามารถรวมเข้ากับโครงการของคุณในรูปแบบต่างๆ สำหรับ C++ จะรองรับไดนามิกไลบรารี ไลบรารีแบบสแตติก และไฟล์ต้นฉบับ สำหรับ Java และ C# รองรับไลบรารีไดนามิกที่มีซอร์สโค้ด wrapper ด้านล่างนี้เป็นวิธีการรวม BqLog:
ที่เก็บโค้ดประกอบด้วยไฟล์ไลบรารีแบบไดนามิกที่คอมไพล์แล้วซึ่งอยู่ใน /dist/dynamic_lib/ หากต้องการรวม BqLog เข้ากับโปรเจ็กต์ของคุณโดยใช้ไฟล์ไลบรารี คุณต้องดำเนินการดังต่อไปนี้:
เลือกไฟล์ไลบรารีแบบไดนามิกที่สอดคล้องกับแพลตฟอร์มของคุณ และเพิ่มลงในระบบบิลด์ของโปรเจ็กต์ของคุณ
คัดลอกไดเร็กทอรี /dist/dynamic_lib/include ลงในโปรเจ็กต์ของคุณ และเพิ่มลงในรายการไดเร็กทอรีรวม (หากคุณใช้ไลบรารี .framework ของ XCode คุณสามารถข้ามขั้นตอนนี้ได้ เนื่องจากไฟล์ .framework มีไฟล์ส่วนหัวอยู่แล้ว)
ที่เก็บโค้ดประกอบด้วยไฟล์ไลบรารีสแตติกที่คอมไพล์แล้วซึ่งอยู่ใน /dist/static_lib/ หากต้องการรวม BqLog เข้ากับโปรเจ็กต์ของคุณโดยใช้ไฟล์ไลบรารี คุณต้องดำเนินการดังต่อไปนี้:
เลือกไฟล์ไลบรารีแบบคงที่ที่สอดคล้องกับแพลตฟอร์มของคุณ และเพิ่มลงในระบบบิลด์ของโปรเจ็กต์ของคุณ
คัดลอกไดเร็กทอรี /dist/static_lib/include ลงในโปรเจ็กต์ของคุณ และเพิ่มลงในรายการไดเร็กทอรีรวม (หากคุณใช้ไลบรารี .framework ของ XCode คุณสามารถข้ามขั้นตอนนี้ได้ เนื่องจากไฟล์ .framework มีไฟล์ส่วนหัวอยู่แล้ว)
BqLog ยังรองรับการรวมซอร์สโค้ดโดยตรงในโครงการของคุณเพื่อการรวบรวม หากต้องการรวม BqLog โดยใช้ซอร์สโค้ด ให้ทำตามขั้นตอนเหล่านี้:
คัดลอกไดเร็กทอรี /src ลงในโปรเจ็กต์ของคุณเพื่อเป็นข้อมูลอ้างอิงซอร์สโค้ด
คัดลอกไดเร็กทอรี /include ลงในโปรเจ็กต์ของคุณ และเพิ่มลงในรายการไดเร็กทอรีรวม
หากคอมไพล์เวอร์ชัน Windows ใน Visual Studio ให้เพิ่ม /Zc:__cplusplus ให้กับตัวเลือกการคอมไพล์เพื่อให้แน่ใจว่ามีการกำหนดการสนับสนุนมาตรฐานคอมไพเลอร์ C++ ปัจจุบันอย่างถูกต้อง
หากใช้ซอร์สโค้ดใน NDK ของ Android โปรดดูที่ 4 เกี่ยวกับ NDK และ ANDROID_STL = ไม่มี สำหรับการพิจารณาที่สำคัญ
ใน C# นั้น BqLog สามารถใช้ผ่านไลบรารีไดนามิกดั้งเดิมและ C# Wrapper ซึ่งรองรับกลไก Mono, Microsoft CLR และ Unity Unity เข้ากันได้กับทั้งโหมด Mono และ IL2CPP หากต้องการใช้ BqLog ใน C# ให้ทำตามขั้นตอนเหล่านี้:
เลือกไฟล์ไลบรารีไดนามิกที่สอดคล้องกับแพลตฟอร์มของคุณจาก /dist/dynamic_lib/ และเพิ่มลงในโปรเจ็กต์ของคุณ (สำหรับ Unity โปรดดูที่ Unity Import และกำหนดค่าปลั๊กอิน)
คัดลอกไฟล์ซอร์สโค้ดจาก /wrapper/csharp/src ลงในโปรเจ็กต์ของคุณ
ใน Java นั้น BqLog สามารถใช้ผ่านไลบรารีไดนามิกดั้งเดิมและ Java Wrapper ซึ่งรองรับสภาพแวดล้อม JVM ทั่วไปและ Android หากต้องการรวม BqLog เข้ากับ JVM ให้ทำตามขั้นตอนเหล่านี้:
เลือกไฟล์ไลบรารีไดนามิกที่สอดคล้องกับแพลตฟอร์มของคุณจาก /dist/dynamic_lib/ และเพิ่มลงในโปรเจ็กต์ของคุณ
คัดลอกไฟล์ซอร์สโค้ดจาก /wrapper/java/src ลงในโปรเจ็กต์ของคุณ
(ทางเลือก) คัดลอกไดเร็กทอรี /dist/dynamic_lib/include ลงในโปรเจ็กต์ของคุณ และเพิ่มลงในรายการไดเร็กทอรีรวม หากคุณต้องการเรียก BqLog จาก NDK
รหัสต่อไปนี้จะส่งออกบันทึกมากกว่า 1,000 รายการไปยังคอนโซลของคุณ (หรือ ADB Logcat หากบน Android)
#ถ้ากำหนด(WIN32) #include#endif#include #include int main() - #if กำหนด (WIN32) // สลับบรรทัดคำสั่ง Windows เป็น UTF-8 เนื่องจาก BqLog ส่งออกข้อความสุดท้ายทั้งหมดในการเข้ารหัส UTF-8 เพื่อหลีกเลี่ยงปัญหาการแสดงผล SetConsoleOutputCP (CP_UTF8); SetConsoleCP(CP_UTF8); #endif // สตริงนี้คือการกำหนดค่าบันทึก ที่นี่จะกำหนดค่าตัวบันทึกด้วยหนึ่ง appender (เป้าหมายเอาต์พุต) ชื่อ appender_0 ซึ่งส่งออกไปยังคอนโซล std::string config = R"( # เป้าหมายเอาต์พุตของ appender นี้คือคอนโซล appenders_config.appender_0.type=console # appender นี้ใช้เวลาท้องถิ่นสำหรับการประทับเวลา appenders_config.appender_0.time_zone=default เวลาท้องถิ่น # appender นี้ส่งออกบันทึกของ 6 ระดับเหล่านี้ (ไม่มีช่องว่างระหว่าง) appenders_config.appender_0.levels=[verbose,debug,info,warning,error,fatal] )"; bq::log log = bq::log::create_log("my_first_log", config); // สร้างวัตถุบันทึกโดยใช้การกำหนดค่าสำหรับ (int i = 0; i < 1024; ++i) { log.info("นี่คือบันทึกทดสอบข้อมูล สตริงรูปแบบคือ UTF-8, param int:{}, param bool :{}, param string8:{}, param string16:{}, param string32:{} , พารามิเตอร์ float:{}", i, true, "utf8-string", u"utf16-string", U"utf32-string", 4.3464f); } log.error(U"นี่คือบันทึกทดสอบข้อผิดพลาด สตริงรูปแบบคือ UTF-32"); bq::log::force_flush_all_logs(); // BqLog มีค่าเริ่มต้นเป็นเอาต์พุตแบบอะซิงโครนัส เพื่อให้แน่ใจว่ามองเห็นบันทึกได้ก่อนออกจากโปรแกรม ให้บังคับฟลัชเพื่อซิงค์เอาต์พุตหนึ่งครั้ง กลับ 0; -
โดยใช้ System.Text; การใช้ระบบ; คลาสสาธารณะ demo_main { โมฆะสาธารณะคงที่ Main (สตริง [] args) { Console.OutputEncoding = การเข้ารหัส UTF8; Console.InputEncoding = การเข้ารหัส UTF8; string config = @" # เป้าหมายเอาต์พุตของ appender นี้คือคอนโซล appenders_config.appender_0.type=console # appender นี้ใช้เวลาท้องถิ่นสำหรับการประทับเวลา ppenders_config.appender_0.time_zone=default เวลาท้องถิ่น # appender นี้ส่งออกบันทึกของ 6 ระดับเหล่านี้ (ไม่มีช่องว่างใน ระหว่าง) appenders_config.appender_0.levels=[verbose,debug,info,warning,error,fatal] "; บันทึก bq.log = bq.log.create_log("my_first_log", config); // สร้างวัตถุบันทึกโดยใช้การกำหนดค่าสำหรับ (int i = 0; i < 1024; ++i) { log.info("นี่คือบันทึกทดสอบข้อมูล สตริงรูปแบบคือ UTF-16, param int:{}, param bool :{}, param string:{}, param float:{}", i, true, " ข้อความสตริง", 4.3464f); - bq.log.force_flush_all_logs(); คอนโซล ReadKey(); -
public class demo_main { public static void main (String [] args) { // TODO วิธีสร้างอัตโนมัติ stub String config = """ # เป้าหมายเอาต์พุตของ appender นี้คือคอนโซล appenders_config.appender_0.type=console # appender นี้ใช้เวลาท้องถิ่น สำหรับการประทับเวลา appenders_config.appender_0.time_zone=default local time # appender นี้จะส่งออกบันทึกของ 6 ระดับเหล่านี้ (ไม่มีช่องว่างระหว่างนั้น) appenders_config.appender_0.levels=[verbose,debug,info,warning,error,fatal] """; บันทึก bq.log = bq.log.create_log("my_first_log", config); // สร้างวัตถุบันทึกโดยใช้การกำหนดค่าสำหรับ (int i = 0; i < 1024; ++i) { log.info("นี่คือบันทึกทดสอบข้อมูล สตริงรูปแบบคือ UTF-16, param int:{}, param bool :{}, param string:{}, param float:{}", i, true, "ข้อความสตริง", 4.3464f); } bq.log.force_flush_all_logs(); - -
แผนภาพด้านบนแสดงให้เห็นโครงสร้างพื้นฐานของ BqLog อย่างชัดเจน ทางด้านขวาของแผนภาพคือการใช้งานไลบรารี BqLog ภายใน ในขณะที่ด้านซ้ายคือโปรแกรมและโค้ดของคุณ โปรแกรมของคุณสามารถเรียก BqLog ได้โดยใช้ wrapper ที่ให้มา (API เชิงวัตถุสำหรับภาษาต่างๆ) ในแผนภาพ จะมีการสร้างบันทึกสองรายการ: รายการหนึ่งชื่อ "Log A" และอีกรายการชื่อ "Log B" บันทึกแต่ละรายการจะแนบอยู่กับผู้ผนวกตั้งแต่หนึ่งรายขึ้นไป Appender สามารถเข้าใจได้ว่าเป็นเป้าหมายเอาต์พุตของเนื้อหาบันทึก ซึ่งอาจเป็นคอนโซล (บันทึก ADB Logcat สำหรับ Android) ไฟล์ข้อความ หรือแม้แต่รูปแบบพิเศษ เช่น ไฟล์บันทึกที่บีบอัด หรือไฟล์รูปแบบบันทึกไบนารีทั่วไป
ภายในกระบวนการเดียวกัน wrappers สำหรับภาษาที่แตกต่างกันจะสามารถเข้าถึงออบเจ็กต์ Log เดียวกันได้ ตัวอย่างเช่น หากอ็อบเจ็กต์ Log ชื่อ Log A ถูกสร้างขึ้นใน Java ก็สามารถเข้าถึงและใช้งานได้จากฝั่ง C++ ด้วยชื่อ Log A
ในกรณีที่ร้ายแรง เช่น เกมที่พัฒนาโดย Unity ที่ทำงานบนระบบ Android คุณอาจเกี่ยวข้องกับภาษา Java, Kotlin, C# และ C++ ภายในแอปเดียวกัน พวกเขาทั้งหมดสามารถแชร์ออบเจ็กต์บันทึกเดียวกันได้ คุณสามารถสร้างบันทึกบนฝั่ง Java ได้โดยใช้ create_log จากนั้นเข้าถึงในภาษาอื่นโดยใช้ get_log_by_name
หมายเหตุ: API ต่อไปนี้ได้รับการประกาศในคลาส bq::log (หรือ bq.log) เพื่อประหยัดพื้นที่ จะแสดงเฉพาะ C++ API เท่านั้น API ใน Java และ C# เหมือนกันและจะไม่ทำซ้ำที่นี่
ใน C++ bq::string
เป็นประเภทสตริง UTF-8 ในไลบรารี BqLog คุณยังสามารถส่งผ่านสตริงสไตล์ c เช่น char หรือ std::string
หรือ std::string_view
ซึ่งจะถูกแปลงโดยอัตโนมัติและโดยปริยาย
คุณสามารถสร้างออบเจ็กต์บันทึกได้โดยใช้ฟังก์ชัน create_log static คำประกาศมีดังนี้:
//C++ API ////// สร้างวัตถุบันทึก /// /// หากชื่อบันทึกเป็นสตริงว่าง bqLog จะกำหนดให้คุณโดยอัตโนมัติ ชื่อบันทึกที่ไม่ซ้ำ หากมีชื่อบันทึกอยู่แล้ว ระบบจะส่งคืนออบเจ็กต์บันทึกที่มีอยู่ก่อนหน้านี้ และเขียนทับการกำหนดค่าก่อนหน้าด้วยการกำหนดค่าใหม่ /// สตริงการกำหนดค่าบันทึก ///ออบเจ็กต์บันทึก หากการสร้างล้มเหลว เมธอด is_valid() จะคืนค่า false บันทึกสแตติก create_log(const bq::string& log_name, const bq::string& config_content);
รหัสสร้างวัตถุบันทึกโดยส่งชื่อของวัตถุบันทึกและสตริงการกำหนดค่า สามารถอ้างอิงการกำหนดค่าบันทึกได้ในคำแนะนำในการกำหนดค่า ต่อไปนี้เป็นประเด็นสำคัญที่ควรทราบ:
ไม่ว่าจะเป็น C# หรือ Java ออบเจ็กต์บันทึกที่ส่งคืนจะไม่เป็นค่าว่าง อย่างไรก็ตาม เนื่องจากข้อผิดพลาดในการกำหนดค่าหรือเหตุผลอื่นๆ อาจมีการสร้างออบเจ็กต์บันทึกที่ไม่ถูกต้อง ดังนั้นคุณควรใช้ฟังก์ชัน is_valid() เพื่อตรวจสอบวัตถุที่ส่งคืน การดำเนินการกับวัตถุที่ไม่ถูกต้องอาจทำให้โปรแกรมหยุดทำงาน
หากมีการส่งสตริงว่างเป็นชื่อบันทึก bqLog จะสร้างชื่อบันทึกที่ไม่ซ้ำกันโดยอัตโนมัติ เช่น "AutoBqLog_1"
การเรียก create_log บนออบเจ็กต์บันทึกที่มีอยู่แล้วด้วยชื่อเดียวกันจะไม่สร้างออบเจ็กต์บันทึกใหม่ แต่จะเขียนทับการกำหนดค่าก่อนหน้าด้วยอันใหม่ อย่างไรก็ตาม พารามิเตอร์บางตัวไม่สามารถแก้ไขได้ในกระบวนการนี้ ดูคำแนะนำในการกำหนดค่าสำหรับรายละเอียด
ยกเว้นเมื่อใช้ใน NDK (โปรดดูที่ 4 เกี่ยวกับ NDK และ ANDROID_STL = none) คุณสามารถเริ่มต้นออบเจ็กต์บันทึกได้โดยตรงในตัวแปรส่วนกลางหรือคงที่โดยใช้ API นี้ในสถานการณ์อื่น
หากวัตถุบันทึกถูกสร้างขึ้นที่อื่นแล้ว คุณสามารถรับวัตถุบันทึกที่สร้างขึ้นได้โดยตรงโดยใช้ฟังก์ชัน get_log_by_name
//C++ API ////// รับวัตถุบันทึกตามชื่อ /// /// ชื่อของวัตถุบันทึกที่คุณต้องการค้นหา ///วัตถุบันทึก หากไม่พบวัตถุบันทึกที่มีชื่อเฉพาะ เมธอด is_valid() ของวัตถุนั้นจะส่งคืนบันทึกคงที่ false get_log_by_name(const bq::string& log_name);
คุณยังสามารถใช้ฟังก์ชันนี้เพื่อเริ่มต้นวัตถุบันทึกในตัวแปรส่วนกลางหรือฟังก์ชันคงที่ อย่างไรก็ตาม โปรดทราบว่าคุณต้องแน่ใจว่ามีออบเจ็กต์บันทึกที่มีชื่อที่ระบุอยู่แล้ว มิฉะนั้น ออบเจ็กต์บันทึกที่ส่งคืนจะใช้งานไม่ได้ และเมธอด is_valid() จะคืนค่าเท็จ
///ฟังก์ชันบันทึกหลัก มี 6 ระดับบันทึก: ///verbose, debug, info, warning, error, fatal templatebq::enable_if_t ::value, bool> verbose(const STR& log_content) const; แม่แบบ <ชื่อประเภท STR ชื่อประเภท...Args> bq::enable_if_t ::value, bool> verbose(const STR& log_format_content, const Args&... args) const; แม่แบบ<ชื่อประเภท STR> bq::enable_if_t ::value, bool> ดีบัก (const STR& log_content) const; แม่แบบ <ชื่อประเภท STR ชื่อประเภท...Args> bq::enable_if_t ::value, bool> ดีบัก (const STR& log_format_content, const Args&... args) const; แม่แบบ<ชื่อประเภท STR> bq::enable_if_t ::value, bool> ข้อมูล (const STR& log_content) const; แม่แบบ <ชื่อประเภท STR ชื่อประเภท...Args> bq::enable_if_t ::value, bool> ข้อมูล (const STR& log_format_content, const Args&... args) const; แม่แบบ<ชื่อประเภท STR> bq::enable_if_t ::value, bool> คำเตือน (const STR& log_content) const; แม่แบบ <ชื่อประเภท STR ชื่อประเภท...Args> bq::enable_if_t ::value, bool> คำเตือน (const STR& log_format_content, const Args&... args) const; แม่แบบ<ชื่อประเภท STR> bq::enable_if_t ::value, bool> ข้อผิดพลาด (const STR& log_content) const; แม่แบบ <ชื่อประเภท STR ชื่อประเภท...Args> bq::enable_if_t ::value, bool> ข้อผิดพลาด (const STR& log_format_content, const Args&... args) const; แม่แบบ<ชื่อประเภท STR> bq::enable_if_t ::value, bool> ร้ายแรง (const STR& log_content) const; แม่แบบ <ชื่อประเภท STR ชื่อประเภท...Args> bq::enable_if_t ::value, bool> ร้ายแรง (const STR& log_format_content, const Args&... args) const;
เมื่อบันทึกข้อความ ให้ใส่ใจกับประเด็นสำคัญสามประการ:
อย่างที่คุณเห็น บันทึกของเราแบ่งออกเป็นหกระดับ: รายละเอียด การแก้ไขข้อบกพร่อง ข้อมูล คำเตือน ข้อผิดพลาด และร้ายแรง ซึ่งสอดคล้องกับ Android ความสำคัญเพิ่มขึ้นตามลำดับ เมื่อส่งออกไปยังคอนโซล จะปรากฏเป็นสีต่างๆ
พารามิเตอร์ STR คล้ายกับพารามิเตอร์แรกของ printf และสามารถเป็นประเภทสตริงทั่วไปได้หลากหลาย รวมถึง:
java.lang.String ของ Java
สตริงของ C#
การเข้ารหัสต่างๆของสตริงสไตล์ C ของ C++ และ std::string
( char*
, char16_t*
, char32_t*
, wchar_t*
, std::string
, std::u8string
, std::u16string
, std::u32string
, std::wstring
, std::string_view
, std::u16string_view
, std::u32string_view
, std::wstring_view
และแม้แต่ประเภทสตริงที่กำหนดเอง ซึ่งคุณสามารถอ้างถึง inCustom parameter Types )
คุณสามารถเพิ่มพารามิเตอร์ต่างๆ หลังพารามิเตอร์ STR พารามิเตอร์เหล่านี้จะถูกจัดรูปแบบให้อยู่ในตำแหน่งที่ระบุใน STR ตามกฎที่คล้ายกับรูปแบบ std:: ของ C ++ 20 (ยกเว้นการขาดการสนับสนุนสำหรับอาร์กิวเมนต์ตำแหน่งและรูปแบบวันที่และเวลา) ตัวอย่างเช่น การใช้ {} เดี่ยวแสดงถึงการจัดรูปแบบเริ่มต้นของพารามิเตอร์ และ {:.2f} ระบุความแม่นยำในการจัดรูปแบบตัวเลขทศนิยม พยายามใช้พารามิเตอร์ที่จัดรูปแบบเพื่อส่งออกบันทึกแทนที่จะต่อสตริงด้วยตนเอง แนวทางนี้เหมาะสมที่สุดสำหรับประสิทธิภาพและการจัดเก็บรูปแบบที่ถูกบีบอัด
ประเภทพารามิเตอร์ที่รองรับในปัจจุบัน ได้แก่ :
ตัวชี้ Null (เอาต์พุตเป็นโมฆะ)
พอยน์เตอร์ (เอาต์พุตเป็นที่อยู่เลขฐานสิบหกที่เริ่มต้นด้วย 0x)
บูล
อักขระไบต์เดียว (อักขระ)
อักขระแบบไบต์คู่ (char16_t, wchar_t, ถ่านของ C#, ถ่านของ Java)
อักขระสี่ไบต์ (char32_t หรือ wchar_t)
จำนวนเต็ม 8 บิต
จำนวนเต็ม 8 บิตที่ไม่ได้ลงนาม
จำนวนเต็ม 16 บิต
จำนวนเต็ม 16 บิตที่ไม่ได้ลงนาม
จำนวนเต็ม 32 บิต
จำนวนเต็ม 32 บิตที่ไม่ได้ลงนาม
จำนวนเต็ม 64 บิต
จำนวนเต็ม 64 บิตที่ไม่ได้ลงนาม
ตัวเลขทศนิยม 32 บิต
ตัวเลขทศนิยม 64 บิต
ประเภท POD ที่ไม่รู้จักอื่นๆ ในภาษา C++ (จำกัดขนาด 1, 2, 4 หรือ 8 ไบต์ โดยถือเป็น int8, int16, int32 และ int64 ตามลำดับ)
สตริง รวมถึงสตริงทุกประเภทที่กล่าวถึงในพารามิเตอร์ STR
คลาสหรือวัตถุใด ๆ ใน C# และ Java (ส่งออกสตริง ToString())
ประเภทพารามิเตอร์ที่กำหนดเอง ดังรายละเอียดในประเภทพารามิเตอร์ที่กำหนดเอง
มี API ที่ใช้กันทั่วไปเพิ่มเติมที่สามารถทำงานเฉพาะเจาะจงให้สำเร็จได้ สำหรับคำอธิบาย API โดยละเอียด โปรดดูที่ bq_log/bq_log.h รวมถึงคลาส bq.log ใน Java และ C# API หลักบางส่วนที่ต้องเน้นมีดังนี้
////// ยกเลิกการเตรียมใช้งาน BqLog โปรดเรียกใช้ฟังก์ชันนี้ก่อนที่โปรแกรมของคุณจะมีอยู่ /// โมฆะคงที่ หน่วย();
ขอแนะนำให้ดำเนินการ uninit()
ก่อนที่จะออกจากโปรแกรมหรือถอนการติดตั้งไลบรารีไดนามิกที่นำไปใช้เองซึ่งใช้ BqLog ไม่เช่นนั้นโปรแกรมอาจค้างเมื่อออกจากโปรแกรมภายใต้สถานการณ์เฉพาะบางประการ
////// หาก bqLog เป็นแบบอะซิงโครนัส ความผิดพลาดในโปรแกรมอาจทำให้บันทึกในบัฟเฟอร์ไม่คงอยู่ในดิสก์ /// หากเปิดใช้งานคุณสมบัตินี้ bqLog จะพยายามทำการล้างบันทึกในบัฟเฟอร์ในกรณีที่เกิดข้อขัดข้อง อย่างไรก็ตาม /// ฟังก์ชันนี้ไม่รับประกันความสำเร็จ และรองรับเฉพาะระบบ POSIX เท่านั้น /// โมฆะคงที่ Enable_auto_crash_handle();
สำหรับคำแนะนำโดยละเอียด โปรดดูที่การปกป้องข้อมูลเมื่อโปรแกรมออกผิดปกติ
////// ล้างบัฟเฟอร์ของออบเจ็กต์บันทึกทั้งหมดแบบซิงโครนัส /// เพื่อให้แน่ใจว่าข้อมูลทั้งหมดในบัฟเฟอร์ได้รับการประมวลผลหลังการโทร /// โมฆะคงที่ force_flush_all_logs(); ////// ล้างบัฟเฟอร์ของวัตถุบันทึกนี้แบบซิงโครนัส /// เพื่อให้แน่ใจว่าข้อมูลทั้งหมดในบัฟเฟอร์ได้รับการประมวลผลหลังจากการเรียก /// เป็นโมฆะ force_flush();
เนื่องจาก bqLog ใช้การบันทึกแบบอะซิงโครนัสตามค่าเริ่มต้น จึงมีบางครั้งที่คุณอาจต้องการซิงโครไนซ์และส่งออกบันทึกทั้งหมดทันที ในกรณีเช่นนี้ คุณจะต้องบังคับเรียก force_flush()
////// ลงทะเบียนการโทรกลับที่จะถูกเรียกใช้เมื่อใดก็ตามที่ข้อความบันทึกคอนโซลถูกส่งออก /// สามารถใช้สำหรับระบบภายนอกเพื่อตรวจสอบเอาต์พุตบันทึกของคอนโซล /// /// โมฆะคง register_console_callback(bq::type_func_ptr_console_callback โทรกลับ); ////// ยกเลิกการลงทะเบียนการเรียกกลับคอนโซล /// /// โมฆะคง unregister_console_callback(bq::type_func_ptr_console_callback โทรกลับ);
ผลลัพธ์ของConsoleAppender ไปที่คอนโซลหรือบันทึก ADB Logcat บน Android แต่อาจไม่ครอบคลุมทุกสถานการณ์ ตัวอย่างเช่น ในเอ็นจิ้นเกมแบบกำหนดเองหรือ IDE แบบกำหนดเอง จะมีกลไกให้เรียกใช้ฟังก์ชันเรียกกลับสำหรับเอาต์พุตบันทึกคอนโซลแต่ละรายการ สิ่งนี้ทำให้คุณสามารถประมวลผลใหม่และส่งออกบันทึกคอนโซลได้ทุกที่ในโปรแกรมของคุณ
ข้อควรระวังเพิ่มเติม: อย่าส่งออกบันทึก BQ ที่ซิงโครไนซ์ภายในคอนโซลเรียกกลับ เนื่องจากอาจทำให้เกิดการหยุดชะงักได้ง่าย
////// เปิดใช้งานหรือปิดใช้งานบัฟเฟอร์ส่วนต่อท้ายคอนโซล /// เนื่องจาก wrapper ของเราอาจทำงานได้ทั้งในเครื่องเสมือน C# และ Java และเราไม่ต้องการเรียกการเรียกกลับโดยตรงจากเธรดดั้งเดิม /// เราจึงสามารถเปิดใช้งานตัวเลือกนี้ได้ ด้วยวิธีนี้ เอาต์พุตคอนโซลทั้งหมดจะถูกบันทึกไว้ในบัฟเฟอร์จนกว่าเราจะดึงข้อมูลเหล่านั้น /// /// ///โมฆะคงที่ set_console_buffer_enable(เปิดใช้งานบูล); /// /// ดึงข้อมูลและลบรายการบันทึกออกจากบัฟเฟอร์ตัวต่อคอนโซลในลักษณะที่ปลอดภัยต่อเธรด /// ถ้าบัฟเฟอร์ appender คอนโซลไม่ว่างเปล่า ฟังก์ชัน on_console_callback จะถูกเรียกใช้สำหรับรายการบันทึกนี้ /// โปรดตรวจสอบให้แน่ใจว่าไม่ได้ส่งออกบันทึก BQ ที่ซิงโครไนซ์ภายในฟังก์ชันการโทรกลับ /// /// ฟังก์ชันการเรียกกลับที่จะเรียกใช้สำหรับรายการบันทึกที่ดึงมาหากบัฟเฟอร์ตัวต่อคอนโซลไม่ว่างเปล่า ///จริงถ้า บัฟเฟอร์ส่วนต่อท้ายคอนโซลไม่ว่างเปล่าและดึงข้อมูลรายการบันทึก มิฉะนั้นจะส่งคืนค่า False บูลแบบคงที่ fetch_and_remove_console_buffer(bq::type_func_ptr_console_callback on_console_callback);
นอกเหนือจากการสกัดกั้นเอาต์พุตของคอนโซลผ่านการเรียกกลับของคอนโซลแล้ว คุณยังสามารถดึงข้อมูลเอาต์พุตบันทึกของคอนโซลได้ บางครั้ง เราอาจไม่ต้องการให้เอาต์พุตบันทึกคอนโซลถูกส่งผ่านการเรียกกลับเนื่องจากคุณไม่ทราบว่าเธรดใดที่การโทรกลับจะมาจาก (ตัวอย่างเช่น ในเครื่องเสมือน C# หรือ JVM บางเครื่อง VM อาจดำเนินการรวบรวมขยะเมื่อคอนโซล เรียกกลับซึ่งอาจทำให้แฮงค์หรือขัดข้องได้)
วิธีการที่ใช้ในที่นี้เกี่ยวข้องกับการเปิดใช้งานคอนโซลบัฟเฟอร์ผ่าน set_console_buffer_enable
ซึ่งจะทำให้ทุกเอาต์พุตบันทึกของคอนโซลถูกจัดเก็บไว้ในหน่วยความจำจนกว่าเราจะเรียก fetch_and_remove_console_buffer
เพื่อดึงข้อมูลออกมา ดังนั้น หากคุณเลือกที่จะใช้วิธีนี้ อย่าลืมดึงข้อมูลและล้างบันทึกทันทีเพื่อหลีกเลี่ยงหน่วยความจำที่ยังไม่ได้เผยแพร่
ข้อควรระวังเพิ่มเติม: อย่าส่งออกบันทึก BQ ที่ซิงโครไนซ์ภายในคอนโซลเรียกกลับ เนื่องจากอาจทำให้เกิดการหยุดชะงักได้ง่าย
ข้อควรระวังเพิ่มเติม: หากคุณใช้โค้ดนี้ในสภาพแวดล้อม IL2CPP โปรดตรวจสอบให้แน่ใจว่า on_console_callback ถูกทำเครื่องหมายว่าไม่ปลอดภัยแบบคงที่ และตกแต่งด้วยแอตทริบิวต์ [MonoPInurgeCallback(typeof(type_console_callback))]
////// แก้ไขการกำหนดค่าบันทึก แต่บางฟิลด์ เช่น buffer_size ไม่สามารถแก้ไขได้ /// /// ///bool reset_config(const bq::string& config_content);
บางครั้งคุณอาจต้องการแก้ไขการกำหนดค่าของบันทึกภายในโปรแกรมของคุณ นอกเหนือจากการสร้างออบเจ็กต์บันทึกใหม่เพื่อเขียนทับการกำหนดค่า (โปรดดูการสร้างออบเจ็กต์บันทึก) คุณยังสามารถใช้อินเทอร์เฟซการรีเซ็ตได้อีกด้วย อย่างไรก็ตาม โปรดทราบว่ารายการการกำหนดค่าบางรายการไม่สามารถแก้ไขได้ด้วยวิธีนี้ สำหรับรายละเอียด โปรดดูคำแนะนำในการกำหนดค่า
////// ปิดการใช้งานหรือเปิดใช้งาน Appender เฉพาะชั่วคราว /// /// /// void set_appenders_enable(const bq::string& appender_name, บูลเปิดใช้งาน) ;
ตามค่าเริ่มต้น Appenders ในการกำหนดค่าจะทำงานอยู่ แต่มีกลไกให้ไว้ที่นี่เพื่อปิดใช้งานชั่วคราวและเปิดใช้งานอีกครั้ง
////// ใช้งานได้เฉพาะเมื่อมีการกำหนดค่าสแนปช็อตเท่านั้น /// มันจะถอดรหัสบัฟเฟอร์สแน็ปช็อตเป็นข้อความ /// /// ว่าการประทับเวลาของแต่ละบันทึกเป็นเวลา GMT หรือเวลาท้องถิ่น ///บัฟเฟอร์สแน็ปช็อตที่ถอดรหัส bq::string take_snapshot(บูล use_gmt_time) const;
บางครั้ง คุณลักษณะพิเศษบางอย่างจำเป็นต้องแสดงส่วนสุดท้ายของบันทึก ซึ่งสามารถทำได้โดยใช้คุณลักษณะสแน็ปช็อต หากต้องการเปิดใช้งานคุณสมบัตินี้ คุณต้องเปิดใช้งานสแน็ปช็อตในการกำหนดค่าบันทึกก่อนและตั้งค่าขนาดบัฟเฟอร์สูงสุดเป็นไบต์ นอกจากนี้ คุณต้องระบุระดับบันทึกและหมวดหมู่ที่จะกรองสำหรับสแนปชอต (ไม่บังคับ) สำหรับการกำหนดค่าโดยละเอียด โปรดดูที่การกำหนดค่า Snapshot เมื่อจำเป็นต้องใช้สแนปช็อต การเรียก take_snapshot() จะส่งคืนสตริงที่จัดรูปแบบซึ่งมีรายการบันทึกล่าสุดที่จัดเก็บไว้ในบัฟเฟอร์สแนปช็อต ใน C++ ประเภทคือ bq::string
ซึ่งสามารถแปลงเป็น std::string
โดยปริยายได้
namespace bq{ เครื่องมือเนมสเปซ { //นี่คือคลาสยูทิลิตี้สำหรับการถอดรหัสรูปแบบบันทึกไบนารี //หากต้องการใช้งาน ขั้นแรกให้สร้างวัตถุ log_decoder //จากนั้นเรียกใช้ฟังก์ชันถอดรหัสเพื่อถอดรหัส //หลังจากการโทรสำเร็จแต่ละครั้ง //คุณสามารถใช้ get_last_decoded_log_entry() เพื่อดึงข้อมูลผลลัพธ์ที่ถอดรหัสได้ //การโทรแต่ละครั้งจะถอดรหัสหนึ่งรายการบันทึก struct log_decoder { ส่วนตัว: bq::สตริง decode_text_; bq::appender_decode_result result_ = bq::appender_decode_result::success; uint32_t หมายเลขอ้างอิง_ = 0; สาธารณะ: ////// สร้างวัตถุ log_decoder โดยแต่ละวัตถุ log_decoder สอดคล้องกับไฟล์บันทึกไบนารี /// /// เส้นทางของไฟล์บันทึกไบนารี อาจเป็นเส้นทางสัมพัทธ์หรือเส้นทางสัมบูรณ์ log_decoder(const bq::string& log_file_path); ~log_decoder(); ////// ถอดรหัสรายการบันทึก การเรียกใช้ฟังก์ชันนี้จะถอดรหัสเพียง 1 รายการบันทึก /// ///ผลการถอดรหัส appender_decode_result::eof หมายความว่าไฟล์บันทึกทั้งหมดถูกถอดรหัส bq::appender_decode_result ถอดรหัส (); ////// รับผลการถอดรหัสล่าสุด /// ///bq::appender_decode_result get_last_decode_result() const; /// /// รับเนื้อหารายการบันทึกการถอดรหัสล่าสุด /// ///const bq::string& get_last_decoded_log_entry() const; - - -
นี่คือคลาสยูทิลิตี้ที่สามารถถอดรหัสเอาต์พุตไฟล์บันทึกโดย Appender ประเภทไบนารี ณ รันไทม์ เช่น CompressedFileAppender และ RawFileAppender
หากต้องการใช้งาน ให้สร้างอ็อบเจ็กต์ log_decoder ก่อน จากนั้น แต่ละครั้งที่คุณเรียกใช้ฟังก์ชัน decode() ฟังก์ชันจะถอดรหัสหนึ่งรายการบันทึกตามลำดับ หากผลลัพธ์ที่ส่งคืนคือ bq::appender_decode_result::success คุณสามารถเรียก get_last_decoded_log_entry() เพื่อรับเนื้อหาข้อความที่จัดรูปแบบของรายการบันทึกที่ถอดรหัสล่าสุด หากผลลัพธ์เป็น bq::appender_decode_result::eof แสดงว่าบันทึกทั้งหมดได้รับการอ่านอย่างสมบูรณ์แล้ว
BqLog ช่วยให้คุณสามารถกำหนดค่าว่าวัตถุบันทึกเป็นแบบซิงโครนัสหรืออะซิงโครนัสผ่านการตั้งค่า thread_mode ความแตกต่างที่สำคัญระหว่างสองโหมดนี้มีดังนี้:
การบันทึกแบบซิงโครนัส | การบันทึกแบบอะซิงโครนัส | |
---|---|---|
พฤติกรรม | หลังจากเรียกใช้ฟังก์ชันการบันทึก บันทึกจะถูกเขียนไปยังภาคผนวกที่เกี่ยวข้องทันที | หลังจากเรียกใช้ฟังก์ชันการบันทึก บันทึกจะไม่ถูกเขียนทันที แต่จะถูกส่งไปยังเธรดผู้ปฏิบัติงานเพื่อการประมวลผลเป็นระยะแทน |
ผลงาน | ต่ำ เนื่องจากเธรดที่เขียนบันทึกจำเป็นต้องบล็อกและรอให้เขียนบันทึกไปยังผู้ผนวกที่เกี่ยวข้องก่อนที่จะกลับจากฟังก์ชันการบันทึก | สูง เนื่องจากเธรดที่เขียนบันทึกไม่จำเป็นต้องรอเอาต์พุตจริงและสามารถกลับมาได้ทันทีหลังจากการบันทึก |
ความปลอดภัยของด้าย | สูง แต่ต้องการให้พารามิเตอร์บันทึกไม่ได้รับการแก้ไขระหว่างการทำงานของฟังก์ชันการบันทึก | สูง แต่ต้องการให้พารามิเตอร์บันทึกไม่ได้รับการแก้ไขระหว่างการทำงานของฟังก์ชันการบันทึก |
ความเข้าใจผิดทั่วไปเกี่ยวกับการบันทึกแบบอะซิงโครนัสคือ มีความปลอดภัยของเธรดน้อยกว่า โดยผู้ใช้กังวลว่าพารามิเตอร์อาจถูกเรียกคืนตามเวลาที่เธรดของผู้ปฏิบัติงานประมวลผลบันทึก ตัวอย่างเช่น:
{ const char str_array[5] = {'T', 'E', 'S', 'T', '�'}; const ถ่าน* str_ptr = str_array; log_obj.info("นี่คือพารามิเตอร์ทดสอบ: {}, {}", str_array, str_ptr); -
ในตัวอย่างข้างต้น str_array
จะถูกจัดเก็บไว้ในสแต็ก และเมื่อออกจากขอบเขตแล้ว หน่วยความจำของมันจะใช้งานไม่ได้อีกต่อไป ผู้ใช้อาจกังวลว่าหากใช้การบันทึกแบบอะซิงโครนัส เมื่อเธรดผู้ปฏิบัติงานประมวลผลบันทึก str_array
และ str_ptr
จะเป็นตัวแปรที่ไม่ถูกต้อง
อย่างไรก็ตาม สถานการณ์ดังกล่าวจะไม่เกิดขึ้นเนื่องจาก BqLog คัดลอกเนื้อหาพารามิเตอร์ทั้งหมดลงใน ring_buffer
ภายในระหว่างการดำเนินการฟังก์ชัน info
เมื่อฟังก์ชัน info
กลับมาแล้ว ก็ไม่จำเป็นต้องใช้ตัวแปรภายนอก เช่น str_array
หรือ str_ptr
อีกต่อไป นอกจากนี้ ring_buffer
จะไม่จัดเก็บที่อยู่ตัวชี้ const char*
แต่จะเก็บสตริงทั้งหมดเสมอ
ปัญหาที่อาจเกิดขึ้นจริงเกิดขึ้นในสถานการณ์ต่อไปนี้:
คงที่ std::string global_str = "สวัสดีชาวโลก"; // นี่คือตัวแปรโกลบอลที่ถูกแก้ไขโดยหลาย threads.void thread_a() - log_obj.info("นี่คือพารามิเตอร์ทดสอบ: {}", global_str); -
หากเนื้อหาของ global_str
เปลี่ยนแปลงระหว่างการดำเนินการฟังก์ชัน info
อาจทำให้เกิดลักษณะการทำงานที่ไม่ได้กำหนดไว้ BqLog จะพยายามอย่างเต็มที่เพื่อป้องกันความผิดพลาด แต่ไม่สามารถรับประกันความถูกต้องของผลลัพธ์สุดท้ายได้
Appender แสดงถึงเป้าหมายเอาต์พุตบันทึก แนวคิดของ Appenders ใน bqLog โดยพื้นฐานแล้วจะเหมือนกับใน Log4j ปัจจุบัน bqLog มี Appender ประเภทต่อไปนี้:
เป้าหมายเอาต์พุตของ Appender นี้คือคอนโซล รวมถึง ADB ของ Android และคอนโซลที่เกี่ยวข้องบน iOS การเข้ารหัสข้อความคือ UTF-8
Appender นี้ส่งออกไฟล์บันทึกโดยตรงในรูปแบบข้อความ UTF-8
Appender นี้ส่งออกไฟล์บันทึกในรูปแบบบีบอัด ซึ่งเป็น highly recommended format by bqLog
มันมีประสิทธิภาพสูงสุดในบรรดา Appender ทั้งหมดและสร้างไฟล์เอาต์พุตที่เล็กที่สุด อย่างไรก็ตาม จำเป็นต้องถอดรหัสไฟล์สุดท้าย การถอดรหัสสามารถทำได้ที่การถอดรหัสรันไทม์หรือการถอดรหัสแบบออฟไลน์
ภาคผนวกนี้จะส่งออกเนื้อหาบันทึกไบนารีจากหน่วยความจำไปยังไฟล์โดยตรง ประสิทธิภาพของมันสูงกว่า TextFileAppender แต่ใช้พื้นที่เก็บข้อมูลมากกว่า ไฟล์สุดท้ายจะต้องได้รับการถอดรหัส การถอดรหัสสามารถทำได้ที่การถอดรหัสรันไทม์หรือการถอดรหัสออฟไลน์ ไม่แนะนำให้ใช้ Appender นี้
ด้านล่างนี้เป็นการเปรียบเทียบที่ครอบคลุมของผู้ผนวกต่างๆ:
ชื่อ | เป้าหมายเอาท์พุต | อ่านได้โดยตรง | ประสิทธิภาพเอาต์พุต | ขนาดเอาต์พุต |
---|---|---|---|---|
ConsoleAppender | คอนโซล | ต่ำ | - | |
TextFileAppender | ไฟล์ | ต่ำ | ใหญ่ | |
CompressedFileAppender | ไฟล์ | สูง | เล็ก | |
RawFileAppender | ไฟล์ | ปานกลาง | ใหญ่ |
การกำหนดค่าอ้างอิงถึงสตริงการกำหนดค่าในฟังก์ชัน create_log และ reset_config สตริงนี้ใช้รูปแบบไฟล์คุณสมบัติและรองรับ # ความคิดเห็น (แต่อย่าลืมขึ้นบรรทัดใหม่ด้วย # สำหรับความคิดเห็น)
ด้านล่างนี้เป็นตัวอย่างที่สมบูรณ์:
# การกำหนดค่านี้ตั้งค่าออบเจ็กต์บันทึกที่มีส่วนต่อท้ายทั้งหมด 5 รายการ รวมถึง TextFileAppender สองตัวที่ส่งออกไปยังไฟล์ที่แตกต่างกันสองไฟล์ # Appender ตัวแรกชื่อ appender_0 และประเภทคือ ConsoleAppenderappenders_config.appender_0.type=console# โซนเวลาสำหรับ appender_0 คือ เวลาท้องถิ่นของระบบ appenders_config.appender_0.time_zone=default local time# appender_0 จะส่งออกบันทึกทั้งหมด 6 ระดับ (หมายเหตุ: ไม่ควรมีช่องว่างระหว่างระดับบันทึก ไม่เช่นนั้นจะไม่สามารถแยกวิเคราะห์ได้)appenders_config.appender_0.levels=[verbose,debug ,ข้อมูล,คำเตือน,ข้อผิดพลาด,ร้ายแรง]# Appender ตัวที่สองชื่อ appender_1 และประเภทของมันคือ TextFileAppenderappenders_config.appender_1.type=text_file# โซนเวลาสำหรับ appender_1 คือ GMT ซึ่งเป็น UTC+0appenders_config.appender_1.time_zone=gmt# appender_1 เท่านั้น บันทึกเอาต์พุตของข้อมูลระดับขึ้นไป ส่วนอื่นๆ จะถูกละเว้นappenders_config.appender_1.levels=[info,warning,error,fatal]# พาธสำหรับ appender_1 จะอยู่ในไดเร็กทอรี bqLog สัมพัทธ์ของโปรแกรม โดยมีชื่อไฟล์ที่ขึ้นต้นด้วย Normal ตามด้วย วันที่และ .log extension# บน iOS จะถูกบันทึกไว้ใน /var/mobile/Containers/Data/Application/[APP]/Library/Caches/bqLog# บน Android จะถูกบันทึกไว้ใน [android.content.Context .getExternalFilesDir()]/bqLogappenders_config.appender_1.file_name=bqLog/normal# ขนาดไฟล์สูงสุดคือ 10,000,000 ไบต์; หากเกิน ไฟล์ใหม่จะถูกสร้างขึ้นappenders_config.appender_1.max_file_size=10000000# ไฟล์ที่เก่ากว่าสิบวันจะถูกล้างข้อมูล appenders_config.appender_1.expire_time_days=10# หากขนาดรวมของเอาต์พุตเกิน 100,000,000 ไบต์ ไฟล์จะถูกล้างโดยเริ่มจาก ที่เก่าแก่ที่สุดappenders_config.appender_1.capacity_limit=100000000# Appender ตัวที่สามชื่อ appender_2 และประเภทของมันคือ TextFileAppenderappenders_config.appender_2.type=text_file# appender_2 จะส่งออกทุกระดับของ logsappenders_config.appender_2.levels=[all]# พาธสำหรับ appender_2 จะอยู่ใน ไดเร็กทอรี bqLog สัมพัทธ์ของโปรแกรม โดยชื่อไฟล์ขึ้นต้นด้วย new_normal ตามด้วยวันที่ และ .log extensionappenders_config.appender_2.file_name=bqLog/new_normal# ตัวเลือกนี้มีผลเฉพาะกับ Android โดยบันทึกบันทึกในไดเร็กทอรีจัดเก็บข้อมูลภายในซึ่งก็คือ [android .content.Context.getFilesDir()]/bqLogappenders_config.appender_2.is_in_sandbox=true# Appender ตัวที่สี่ชื่อ appender_3 และประเภทคือ CompressedFileAppenderappenders_config.appender_3.type=compressed_file# appender_3 จะเอาต์พุตทุกระดับของ logsappenders_config.appender_3.levels=[ทั้งหมด ]# เส้นทางสำหรับ appender_3 จะอยู่ในเส้นทางสัมบูรณ์ ~/bqLog ไดเร็กทอรีของโปรแกรม โดยมีชื่อไฟล์ที่ขึ้นต้นด้วย compress_log ตามด้วยวันที่และ .logcompr extensionappenders_config.appender_3.file_name=~/bqLog/compress_log# ชื่อ Appender ที่ห้า appender_4 และประเภทของมันคือ RawFileAppenderappenders_config.appender_4.type=raw_file# appender_4 ถูกปิดใช้งานโดยค่าเริ่มต้นและสามารถเปิดใช้งานได้ในภายหลังโดยใช้ set_appenders_enableappenders_config.appender_4.enable=false# appender_4 จะส่งออกทุกระดับของ logsappenders_config.appender_4.levels=[all]# เส้นทาง สำหรับ appender_4 จะอยู่ในไดเร็กทอรี bqLog สัมพัทธ์ของโปรแกรม โดยมีชื่อไฟล์ที่ขึ้นต้นด้วย raw_log ตามด้วยวันที่และ .loraw extensionappenders_config.appender_4.file_name=bqLog/raw_log# บันทึกจะถูกประมวลผลหากหมวดหมู่เริ่มต้นด้วย ModuleA, ModuleB SystemC มิฉะนั้น ทั้งหมดจะถูกละเว้น (แนวคิดของประเภทจะอธิบายในรายละเอียดในหัวข้อการใช้งานขั้นสูงในภายหลัง)appenders_config.appender_4.categories_mask=[ModuleA,ModuleB.SystemC]# ขนาดบัฟเฟอร์แบบอะซิงโครนัสทั้งหมดคือ 65535 ไบต์ มีการอธิบายความหมายเฉพาะในภายหลังlog.buffer_size=65535# ระดับความน่าเชื่อถือของบันทึกเป็นปกติ มีการอธิบายความหมายเฉพาะในภายหลังlog.reliable_level=normal# บันทึกจะถูกประมวลผลหากหมวดหมู่ตรงกับไวด์การ์ดสามรายการต่อไปนี้ มิฉะนั้นทั้งหมดจะถูกละเว้น (แนวคิดของหมวดหมู่จะอธิบายรายละเอียดในหัวข้อการใช้งานขั้นสูงในภายหลัง)log.categories_mask= [*default,ModuleA,ModuleB.SystemC]# นี่คือบันทึกแบบอะซิงโครนัส บันทึกแบบอะซิงโครนัสเป็นบันทึกที่มีประสิทธิภาพสูงสุดและแนะนำ typelog.thread_mode=async# หากระดับบันทึกมีข้อผิดพลาดหรือร้ายแรง ให้รวมข้อมูล call stack ไว้กับแต่ละรายการบันทึก log.print_stack_levels=[error,fatal]# เปิดใช้งานฟังก์ชันสแนปช็อต ขนาดแคชสแน็ปช็อตคือ 64Ksnapshot .buffer_size=65536# เฉพาะบันทึกที่มีข้อมูลและระดับข้อผิดพลาดเท่านั้นที่จะถูกบันทึกใน snapshotsnapshot.levels=[info,error]# เฉพาะบันทึกที่มีหมวดหมู่ขึ้นต้นด้วย ModuleA, ModuleB.SystemC จะถูกบันทึกในสแน็ปช็อต มิฉะนั้นจะถูกละเว้นสแนปชอต .categories_mask=[ModuleA.SystemA.ClassA,ModuleB]
appenders_config
คือชุดการกำหนดค่าสำหรับ Appenders พารามิเตอร์แรกที่ตามหลัง appenders_config
คือชื่อของ Appender และ Appenders ทั้งหมดที่มีชื่อเดียวกันจะใช้การกำหนดค่าเดียวกันร่วมกัน
ชื่อ | ที่จำเป็น | ค่าที่กำหนดค่าได้ | ค่าเริ่มต้น | ใช้ได้กับ ConsoleAppender | ใช้ได้กับ TextFileAppender | ใช้ได้กับ CompressedFileAppender | ใช้ได้กับ RawFileAppender |
---|---|---|---|---|---|---|---|
พิมพ์ | คอนโซล, text_file, บีบอัด_ไฟล์, raw_file | ||||||
เปิดใช้งาน | ไม่ว่า Appender จะเปิดใช้งานตามค่าเริ่มต้นหรือไม่ | จริง | |||||
ระดับ | อาร์เรย์ของระดับบันทึก | [ทั้งหมด] | |||||
เวลา_โซน | gmt หรือสตริงอื่น ๆ | เวลาท้องถิ่น | |||||
file_name | เส้นทางสัมพัทธ์หรือสัมบูรณ์ | ||||||
is_in_sandbox | จริงเท็จ | เท็จ | |||||
max_file_size | จำนวนเต็มบวกหรือ 0 | 0 | |||||
หมดอายุ_เวลา_วัน | จำนวนเต็มบวกหรือ 0 | 0 | |||||
ความจุ_ขีดจำกัด | จำนวนเต็มบวกหรือ 0 | 0 | |||||
Category_mask | อาร์เรย์ของสตริงที่อยู่ใน [] | ว่างเปล่า |
ระบุประเภทของ Appender
console
: แสดงถึง ConsoleAppender
text_file
: แสดงถึง TextFileAppender
compressed_file
: แสดงถึง CompressedFileAppender
raw_file
: แสดงถึง RawFileAppender
ค่าเริ่มต้นเป็น true
หากตั้งค่าเป็น false
Appender จะถูกปิดใช้งานโดยค่าเริ่มต้น และสามารถเปิดใช้งานได้ในภายหลังโดยใช้ set_appenders_enable
อาร์เรย์ที่อยู่ใน []
ซึ่งมีการรวมกันของ verbose
, debug
, info
, warning
, error
, fatal
หรือ [all]
เพื่อยอมรับทุกระดับ หมายเหตุ: อย่าเว้นวรรคระหว่างระดับ ไม่เช่นนั้นจะแยกวิเคราะห์ไม่ได้
ระบุโซนเวลาของบันทึก gmt
แสดงถึงเวลามาตรฐานกรีนิช (UTC+0) และสตริงอื่นๆ หรือปล่อยว่างไว้จะใช้เขตเวลาท้องถิ่น เขตเวลาส่งผลต่อสองสิ่ง:
การประทับเวลาของบันทึกข้อความที่จัดรูปแบบ (ใช้ได้กับ ConsoleAppender และ TextFileAppender)
ไฟล์บันทึกใหม่จะถูกสร้างขึ้นเมื่อข้ามเวลาเที่ยงคืนในเขตเวลาที่ระบุ (ใช้ได้กับ TextFileAppender, CompressedFileAppender และ RawFileAppender)
เส้นทางและคำนำหน้าชื่อไฟล์สำหรับการบันทึกไฟล์ เส้นทางอาจเป็นเส้นทางแบบสัมบูรณ์ (ไม่แนะนำสำหรับ Android และ iOS) หรือแบบสัมพัทธ์ ชื่อไฟล์เอาต์พุตสุดท้ายจะเป็นพาธและชื่อนี้ ตามด้วยวันที่ หมายเลขไฟล์ และนามสกุลของ Appender
มีความหมายเฉพาะบน Android:
true
: ไฟล์จะถูกจัดเก็บไว้ในไดเร็กทอรี Internal Storage (android.content.Context.getFilesDir()) หากไม่มี ระบบจะจัดเก็บไว้ในไดเร็กทอรีที่จัดเก็บข้อมูลภายนอก (android.content.Context.getExternalFilesDir()) หากยังไม่มี ระบบจะจัดเก็บไว้ในไดเรกทอรี Cache (android.content.Context.getCacheDir())
false
: ไฟล์จะถูกจัดเก็บไว้ในไดเร็กทอรีที่จัดเก็บข้อมูลภายนอกตามค่าเริ่มต้น หากไม่มี ระบบจะจัดเก็บไว้ในไดเร็กทอรี Internal Storage หากไม่มี ข้อมูลเหล่านั้นจะถูกจัดเก็บไว้ในไดเร็กทอรี Cache
ขนาดไฟล์สูงสุดเป็นไบต์ เมื่อไฟล์ที่บันทึกเกินขนาดนี้ ไฟล์บันทึกใหม่จะถูกสร้างขึ้น โดยหมายเลขไฟล์จะเพิ่มขึ้นตามลำดับ 0
ปิดใช้งานคุณสมบัตินี้
จำนวนวันสูงสุดในการเก็บไฟล์ ไฟล์ที่เก่ากว่านี้จะถูกลบโดยอัตโนมัติ 0
ปิดใช้งานคุณสมบัตินี้
ขนาดรวมสูงสุดของไฟล์ที่เอาต์พุตโดย Appender นี้ในไดเร็กทอรีเอาต์พุต หากเกินขีดจำกัดนี้ ไฟล์จะถูกลบโดยเริ่มจากไฟล์ที่เก่าที่สุดจนกระทั่งขนาดรวมอยู่ภายในขีดจำกัด 0
ปิดใช้งานคุณสมบัตินี้
หากวัตถุบันทึกเป็นวัตถุบันทึกที่รองรับหมวดหมู่ สามารถใช้เพื่อกรองรายการหมวดหมู่ที่มีลักษณะคล้ายต้นไม้ได้ เมื่ออาร์เรย์ไม่ว่างเปล่า คุณลักษณะนี้จะทำงาน ตัวอย่างเช่น [*default,ModuleA,ModuleB.SystemC]
หมายความว่าบันทึกด้วยหมวดหมู่เริ่มต้น