สิ่งแรกอันดับแรก: นี่คือจุดเริ่มต้นของโครงการโอเพ่นซอร์สที่ขับเคลื่อนโดยชุมชน แสวงหาการสนับสนุนอย่างแข็งขัน ไม่ว่าจะเป็นโค้ด เอกสารประกอบ หรือแนวคิด นอกเหนือจากการมีส่วนร่วมใน SwiftLog
แล้ว ยังมีช่องว่างขนาดใหญ่อีกประการหนึ่งในขณะนี้: SwiftLog
เป็น แพ็คเกจ API ที่พยายามสร้าง API ทั่วไปที่ระบบนิเวศสามารถใช้ได้ เพื่อให้การบันทึกใช้งานได้จริงสำหรับปริมาณงานในโลกแห่งความเป็นจริง เราจำเป็นต้อง มีแบ็กเอนด์การบันทึก ที่เข้ากันได้กับ SwiftLog
ซึ่งจะคงข้อความบันทึกไว้ในไฟล์ แสดงผลเป็นสีที่สวยงามยิ่งขึ้นบนเทอร์มินัล หรือส่งไปที่ Splunk หรือ ELK
สิ่งที่ SwiftLog
มอบให้ในปัจจุบันสามารถพบได้ในเอกสาร API
หากคุณมีแอปพลิเคชัน Swift ฝั่งเซิร์ฟเวอร์ หรืออาจเป็นแอป/ไลบรารีข้ามแพลตฟอร์ม (เช่น Linux และ macOS) และคุณต้องการบันทึก เราคิดว่าการกำหนดเป้าหมายแพ็คเกจ API การบันทึกนี้เป็นแนวคิดที่ดี ด้านล่างนี้คุณจะพบทุกสิ่งที่คุณจำเป็นต้องรู้เพื่อเริ่มต้นใช้งาน
SwiftLog
ได้รับการออกแบบมาสำหรับ Swift 5.8 และใหม่กว่า หากต้องการขึ้นอยู่กับแพ็คเกจ API การบันทึก คุณต้องประกาศการพึ่งพาของคุณใน Package.swift
:
. package ( url : " https://github.com/apple/swift-log.git " , from : " 1.0.0 " ) ,
และไปยังเป้าหมายของแอปพลิเคชัน/ไลบรารีของคุณ ให้เพิ่ม "Logging"
ลงใน dependencies
ของคุณ เช่น:
. target ( name : " BestExampleApp " , dependencies : [
. product ( name : " Logging " , package : " swift-log " )
] ,
// 1) let's import the logging API package
import Logging
// 2) we need to create a logger, the label works similarly to a DispatchQueue label
let logger = Logger ( label : " com.example.BestExampleApp.main " )
// 3) we're now ready to use it
logger . info ( " Hello World! " )
2019-03-13T15:46:38+0000 info: Hello World!
Logger
เริ่มต้น SwiftLog
จัดให้มีการเข้าสู่ระบบคอนโซลขั้นพื้นฐานโดยทันทีผ่าน StreamLogHandler
เป็นไปได้ที่จะเปลี่ยนเอาต์พุตเริ่มต้นเป็น stderr
ดังนี้:
LoggingSystem . bootstrap ( StreamLogHandler . standardError )
StreamLogHandler
มีวัตถุประสงค์หลักเพื่ออำนวยความสะดวกเท่านั้น และไม่มีการปรับแต่งที่สำคัญใดๆ ผู้ดูแลห้องสมุดที่ต้องการสร้างแบ็กเอนด์การบันทึกของตนเองสำหรับการรวมและการใช้งานควรใช้โปรโตคอล LogHandler
โดยตรงตามที่ระบุไว้ในส่วน "ในการใช้งานแบ็กเอนด์การบันทึก"
สำหรับข้อมูลเพิ่มเติม โปรดตรวจสอบเอกสารประกอบ API
คุณสามารถเลือกจากแบ็กเอนด์ต่อไปนี้เพื่อใช้บันทึกของคุณ หากคุณสนใจที่จะนำไปใช้ โปรดดูส่วน "ข้อควรพิจารณาในการติดตั้งใช้งาน" ด้านล่างเพื่ออธิบายวิธีการดำเนินการดังกล่าว รายการไลบรารีที่เข้ากันได้กับ SwiftLog API ที่มีอยู่:
พื้นที่เก็บข้อมูล | คำอธิบายตัวจัดการ |
---|---|
คิทูรา/ฮีเลียมล็อกเกอร์ | แบ็กเอนด์การบันทึกที่ใช้กันอย่างแพร่หลายในระบบนิเวศ Kitura |
ianpartridge/swift-log- syslog.php | แบ็กเอนด์ syslog |
Adorkable/swift-log- รูปแบบและท่อ | แบ็กเอนด์ที่อนุญาตให้ปรับแต่งรูปแบบเอาต์พุตและปลายทางผลลัพธ์ |
chrisaljoudi/swift-log- oslog | แบ็กเอนด์ OSLog Unified Logging สำหรับใช้บนแพลตฟอร์ม Apple หมายเหตุสำคัญ: เราขอแนะนำให้ใช้ os_log โดยตรงตามที่อธิบายไว้ที่นี่ การใช้ os_log ผ่าน Swift-log โดยใช้แบ็กเอนด์นี้จะมีประสิทธิภาพน้อยลง และจะป้องกันการระบุความเป็นส่วนตัวของข้อความด้วย แบ็กเอนด์จะใช้ %{public}@ เป็นสตริงรูปแบบเสมอ และกระตือรือร้นที่จะแปลงการประมาณค่าสตริงทั้งหมดเป็นสตริง ซึ่งมีข้อเสียอยู่สองประการ: 1. ส่วนประกอบคงที่ของการแก้ไขสตริงจะถูกคัดลอกอย่างกระตือรือร้นโดยระบบการบันทึกแบบรวม ซึ่งจะส่งผลให้ประสิทธิภาพการทำงานลดลง 2. ทำให้ข้อความทั้งหมดเป็นแบบสาธารณะ ซึ่งเปลี่ยนนโยบายความเป็นส่วนตัวเริ่มต้นของ os_log และไม่อนุญาตให้ระบุความเป็นส่วนตัวแบบละเอียดของส่วนของข้อความ ในงานที่กำลังดำเนินอยู่แยกต่างหาก Swift API สำหรับ os_log กำลังได้รับการปรับปรุงและทำให้สอดคล้องอย่างใกล้ชิดกับ Swift-log API ข้อมูลอ้างอิง: การรวมระดับการบันทึก การทำให้ os_log ยอมรับการแก้ไขสตริงโดยใช้การตีความเวลาคอมไพล์ |
การเงินทางสมอง/StackdriverLogging | แบ็กเอนด์การบันทึก JSON ที่มีโครงสร้างสำหรับใช้บน Google Cloud Platform กับ Stackdriver logging agent |
DnV1eX/GoogleCloudLogging | ไลบรารีฝั่งไคลเอ็นต์สำหรับบันทึกเหตุการณ์แอปพลิเคชันใน Google Cloud ผ่าน REST API v2 |
ไอ/คอนโซล-ชุด | ตัวบันทึกไปยังเทอร์มินัลปัจจุบันหรือ stdout พร้อมเอาต์พุตแบบมีสไตล์ (ANSI) ตัวบันทึกเริ่มต้นสำหรับแอปพลิเคชัน Vapor ทั้งหมด |
neallester/swift-log-การทดสอบ | ให้การเข้าถึงข้อความบันทึกเพื่อใช้ในการยืนยัน (ภายในเป้าหมายการทดสอบ) |
wlisac/swift-log-slack | แบ็กเอนด์การบันทึกที่ส่งข้อความบันทึกที่สำคัญไปยัง Slack |
NSHipster/swift-log-github-actions | แบ็กเอนด์การบันทึกที่แปลข้อความการบันทึกเป็นคำสั่งเวิร์กโฟลว์สำหรับ GitHub Actions |
stevapple/swift-log-โทรเลข | แบ็กเอนด์การบันทึกที่ส่งข้อความบันทึกไปยังแชท Telegram ใด ๆ (ได้รับแรงบันดาลใจจากและแยกจาก wlisac/swift-log-slack) |
jagreenwood/swift-log-datadog | แบ็กเอนด์การบันทึกซึ่งจะส่งข้อความบันทึกไปยังบริการการจัดการบันทึก Datadog |
google/SwiftLogFireCloud | แบ็กเอนด์การบันทึกสำหรับการบันทึกอนุกรมเวลาซึ่งจะพุชบันทึกเป็นไฟล์แบบแฟลตไปยัง Firebase Cloud Storage |
crspybits/swift-log-file | ตัวบันทึกไฟล์ในเครื่องอย่างง่าย (โดยใช้ Foundation FileManager ) |
ซูชิชอป/ลูกสุนัข | แบ็กเอนด์การบันทึกที่รองรับการขนส่งหลายรายการ (คอนโซล ไฟล์ syslog ฯลฯ ) และมีคุณสมบัติพร้อมการจัดรูปแบบและการหมุนเวียนบันทึกไฟล์ |
พระศิวะหวง/swift-log-SwiftyBeaver | แบ็กเอนด์การบันทึกสำหรับการพิมพ์การบันทึกสีไปยังคอนโซล / ไฟล์ Xcode หรือส่งการบันทึกที่เข้ารหัสไปยังแพลตฟอร์ม SwiftyBeaver |
Apodini/สวิฟท์ล็อก-กวาง | แบ็กเอนด์การบันทึกที่จัดรูปแบบ แคช และส่งข้อมูลบันทึกไปยัง elastic/logstash |
binaryscraping/swift-log-supabase.php | แบ็กเอนด์การบันทึกที่ส่งรายการบันทึกไปยัง Supabase |
kiliankoe/สวิฟท์-ล็อก-เมทริกซ์ | แบ็กเอนด์การบันทึกสำหรับการส่งบันทึกโดยตรงไปยังห้อง Matrix |
DiscordBM/DiscordLogger | การใช้งานการบันทึก Discord เพื่อส่งบันทึกของคุณไปยังช่องทาง Discord ในลักษณะที่ดีและมีตัวเลือกการกำหนดค่ามากมาย รวมถึงความสามารถในการส่งระดับบันทึกที่สำคัญเพียงไม่กี่ระดับ เช่น warning / error / critical |
โกโก้คนตัดไม้ | เฟรมเวิร์กการบันทึกที่รวดเร็วและเรียบง่าย แต่ทรงพลังและยืดหยุ่นสำหรับ macOS, iOS, tvOS และ watchOS ซึ่งรวมถึงแบ็กเอนด์การบันทึกสำหรับบันทึกแบบรวดเร็ว |
rwbutler/swift-log-ecs | แบ็กเอนด์การบันทึกสำหรับการบันทึกในรูปแบบ ECS Log เข้ากันได้กับ Vapor และอนุญาตให้เชื่อมโยง LogHandlers หลายตัว |
ShipBook/swift-log- สมุด เรือ | แบ็กเอนด์การบันทึกที่ส่งรายการบันทึกไปยัง Shipbook - Shipbook ให้พลังแก่คุณในการรวบรวม ค้นหา และวิเคราะห์บันทึกผู้ใช้และข้อยกเว้นในระบบคลาวด์จากระยะไกล ตามผู้ใช้และเซสชัน |
ห้องสมุดของคุณ? | ได้รับการติดต่อ! |
ดีใจที่คุณถาม เราเชื่อว่าสำหรับระบบนิเวศของ Swift บนเซิร์ฟเวอร์ จำเป็นอย่างยิ่งที่จะต้องมี API การบันทึกที่ใครๆ ก็สามารถนำมาใช้ได้ ดังนั้นไลบรารีจำนวนมากจากฝ่ายต่างๆ จึงสามารถเข้าสู่ระบบไปยังปลายทางที่ใช้ร่วมกันได้ หากพูดให้ชัดเจนยิ่งขึ้น หมายความว่าเราเชื่อว่าข้อความบันทึกทั้งหมดจากไลบรารีทั้งหมดจะจบลงในไฟล์ ฐานข้อมูล อินสแตนซ์ Elastic Stack/Splunk หรืออะไรก็ตามที่คุณเลือก
อย่างไรก็ตาม ในโลกแห่งความเป็นจริง มีความคิดเห็นมากมายเกี่ยวกับวิธีการทำงานของระบบการบันทึก ข้อความบันทึกควรมีการจัดรูปแบบอย่างไร และควรเก็บรักษาไว้ที่ไหน/อย่างไร เราคิดว่าเป็นไปไม่ได้ที่จะรอแพ็คเกจการบันทึกเดียวเพื่อรองรับทุกสิ่งที่ต้องการในการปรับใช้เฉพาะ ในขณะที่ยังคงใช้งานง่ายและยังคงประสิทธิภาพอยู่ นั่นเป็นเหตุผลที่เราตัดสินใจตัดปัญหาออกครึ่งหนึ่ง:
แพ็คเกจนี้ให้เฉพาะ API การบันทึกเท่านั้น ดังนั้น SwiftLog
จึงเป็น 'แพ็คเกจ API การบันทึก' SwiftLog
(โดยใช้ LoggingSystem.bootstrap
) สามารถกำหนดค่าเพื่อเลือกการใช้งานแบ็กเอนด์การบันทึกที่เข้ากันได้ วิธีนี้ทำให้แพ็คเกจสามารถนำ API มาใช้ และ แอปพลิเคชัน สามารถเลือกการใช้งานแบ็กเอนด์การบันทึกที่เข้ากันได้ โดยไม่ต้องมีการเปลี่ยนแปลงใดๆ จากไลบรารีใดๆ
เพื่อความครบถ้วนสมบูรณ์: แพ็คเกจ API นี้รวมการใช้งานแบ็กเอนด์การบันทึกที่เรียบง่ายเกินไปและไม่สามารถกำหนดค่าได้ ซึ่งเพียงแค่เขียนข้อความบันทึกทั้งหมดไปที่ stdout
เหตุผลที่รวมการใช้งานแบ็กเอนด์การบันทึกที่ง่ายเกินไปนี้คือเพื่อปรับปรุงประสบการณ์การใช้งานครั้งแรก สมมติว่าคุณเริ่มโปรเจ็กต์และลองใช้ SwiftLog
เป็นครั้งแรก จะเป็นการดีกว่ามากที่จะเห็นสิ่งที่คุณบันทึกไว้ปรากฏบน stdout
ในรูปแบบที่เรียบง่าย แทนที่จะไม่มีอะไรเกิดขึ้นเลย สำหรับแอปพลิเคชันในโลกแห่งความเป็นจริง เราขอแนะนำให้กำหนดค่าการใช้งานแบ็กเอนด์การบันทึกอื่นที่บันทึกในรูปแบบที่คุณต้องการ
Logger
s ใช้เพื่อส่งข้อความบันทึกและเป็นประเภทที่สำคัญที่สุดใน SwiftLog
ดังนั้นการใช้งานจึงควรง่ายที่สุดเท่าที่จะทำได้ โดยทั่วไปจะใช้เพื่อส่งข้อความบันทึกในระดับบันทึกที่แน่นอน ตัวอย่างเช่น:
// logging an informational message
logger . info ( " Hello World! " )
// ouch, something went wrong
logger . error ( " Houston, we have a problem: ( problem ) " )
รองรับระดับบันทึกต่อไปนี้:
trace
debug
info
notice
warning
error
critical
ระดับการบันทึกของตัวบันทึกที่กำหนดสามารถเปลี่ยนแปลงได้ แต่การเปลี่ยนแปลงจะส่งผลต่อตัวบันทึกเฉพาะที่คุณเปลี่ยนเท่านั้น คุณสามารถพูดได้ว่า Logger
เป็น ประเภทค่า ที่เกี่ยวข้องกับระดับบันทึก
เมตาดาต้าการบันทึกคือข้อมูลเมตาที่สามารถแนบไปกับตัวบันทึกเพื่อเพิ่มข้อมูลที่มีความสำคัญเมื่อแก้ไขข้อบกพร่อง ในเซิร์ฟเวอร์ ตัวอย่างปกติคือการแนบคำขอ UUID เข้ากับตัวบันทึกซึ่งจะปรากฏในข้อความบันทึกทั้งหมดที่บันทึกด้วยตัวบันทึกนั้น ตัวอย่าง:
var logger = logger
logger [ metadataKey : " request-uuid " ] = " ( UUID ( ) ) "
logger . info ( " hello world " )
จะพิมพ์
2019-03-13T18:30:02+0000 info: request-uuid=F8633013-3DD8-481C-9256-B296E43443ED hello world
ด้วยการใช้งานแบ็กเอนด์การบันทึกเริ่มต้นที่มาพร้อมกับ SwiftLog
จำเป็นต้องพูด รูปแบบถูกกำหนดโดยแบ็กเอนด์การบันทึกที่คุณเลือกอย่างสมบูรณ์
LogHandler
)หมายเหตุ: หากคุณไม่ต้องการใช้แบ็กเอนด์การบันทึกแบบกำหนดเอง ทุกอย่างในส่วนนี้อาจไม่เกี่ยวข้องมากนัก ดังนั้นโปรดข้ามไปได้เลย
หากต้องการเป็นแบ็กเอนด์การบันทึกที่ใช้งานร่วมกันได้ซึ่งผู้ใช้ SwiftLog
ทุกคนสามารถใช้ได้ คุณต้องทำสองสิ่ง: 1) ใช้ประเภท (โดยปกติจะเป็น struct
) ที่ใช้ LogHandler
ซึ่งเป็นโปรโตคอลที่จัดทำโดย SwiftLog
และ 2) สั่งให้ SwiftLog
ใช้การใช้งานแบ็กเอนด์การบันทึกของคุณ .
การ LogHandler
หรือการบันทึกแบ็กเอนด์คือสิ่งใดก็ตามที่สอดคล้องกับโปรโตคอลต่อไปนี้
public protocol LogHandler {
func log ( level : Logger . Level , message : Logger . Message , metadata : Logger . Metadata ? , source : String , file : String , function : String , line : UInt )
subscript ( metadataKey _ : String ) -> Logger . Metadata . Value ? { get set }
var metadata : Logger . Metadata { get set }
var logLevel : Logger . Level { get set }
}
การสั่งให้ SwiftLog
ใช้แบ็กเอนด์การบันทึกของคุณเป็นสิ่งที่แอปพลิเคชันทั้งหมด (รวมถึงไลบรารีทั้งหมด) ควรใช้นั้นง่ายมาก:
LoggingSystem . bootstrap ( MyLogHandler . init )
LogHandler
ควบคุมส่วนใหญ่ของระบบการบันทึก:
LogHandler
LogHandler
ควบคุมส่วนสำคัญของการกำหนดค่า Logger
สองส่วน ได้แก่:
logger.logLevel
)logger[metadataKey:]
และ logger.metadata
) อย่างไรก็ตาม เพื่อให้ระบบทำงานได้ สิ่งสำคัญคือ LogHandler
จะถือว่าการกำหนดค่าเป็น ประเภทค่า ซึ่งหมายความว่า LogHandler
ควรเป็น struct
และการเปลี่ยนแปลงระดับการบันทึกหรือข้อมูลเมตาของการบันทึกควรส่งผลต่อ LogHandler
ที่ถูกเปลี่ยนแปลงเท่านั้น
อย่างไรก็ตาม ในกรณีพิเศษ LogHandler
จะมีการแทนที่ระดับบันทึกทั่วโลกบางส่วนซึ่งอาจส่งผลต่อ LogHandler
ทั้งหมดที่สร้างขึ้น เป็นที่ยอมรับได้
LogHandler
s LogHandler
ไม่ได้ควบคุมว่าควรบันทึกข้อความหรือไม่ Logger
จะเรียกใช้ฟังก์ชัน log
ของ LogHandler
ก็ต่อเมื่อ Logger
พิจารณาว่าควรส่งข้อความบันทึกตามระดับบันทึกที่กำหนดค่าไว้
Logger
มี label
(ไม่เปลี่ยนรูป) และแต่ละข้อความบันทึกมีพารามิเตอร์ source
(ตั้งแต่ SwiftLog 1.3.0) ป้ายกำกับของ Logger
ระบุถึงผู้สร้าง Logger
หากคุณใช้การบันทึกแบบมีโครงสร้างโดยการเก็บรักษาข้อมูลเมตาในหลายโมดูล label
ของ Logger
ไม่ใช่วิธีที่ดีในการระบุว่าข้อความบันทึกมาจากไหน เนื่องจากระบุผู้สร้าง Logger
ซึ่งมักจะถูกส่งผ่านระหว่างไลบรารีเพื่อรักษาข้อมูลเมตาและ ชอบ
หากคุณต้องการกรองข้อความบันทึกทั้งหมดที่มาจากระบบย่อยบางระบบ ให้กรองตาม source
มาซึ่งมีค่าเริ่มต้นเป็นโมดูลที่ส่งข้อความบันทึก
โปรดดู SECURITY.md สำหรับกระบวนการรักษาความปลอดภัยของ SwiftLog
API การบันทึกนี้ได้รับการออกแบบร่วมกับผู้ร่วมให้ข้อมูลในชุมชน Swift บนเซิร์ฟเวอร์ และได้รับการอนุมัติโดย SSWG (Swift Server Work Group) ให้เป็น 'ระดับแซนด์บ็อกซ์' ของกระบวนการบ่มเพาะของ SSWG