LogStashLogger ขยายคลาส Logger
ของ Ruby เพื่อเข้าสู่ระบบ Logstash โดยตรง รองรับการเขียนไปยังเอาต์พุตต่างๆ ในรูปแบบ logstash JSON นี่เป็นการปรับปรุงจากการเขียนไฟล์หรือ syslog เนื่องจาก Logstash สามารถรับข้อมูลที่มีโครงสร้างได้โดยตรง
สามารถเขียนโดยตรงไปยังตัวฟัง logstash ผ่านการเชื่อมต่อ UDP หรือ TCP/SSL
สามารถเขียนลงในไฟล์, Redis, Kafka, Kinesis, Firehose, ซ็อกเก็ต unix, syslog, stdout หรือ stderr
Logger สามารถรับข้อความสตริง แฮช LogStash::Event
วัตถุ หรือสตริง JSON เป็นอินพุตได้
กิจกรรมจะถูกเติมด้วยข้อความ การประทับเวลา โฮสต์ และความรุนแรงโดยอัตโนมัติ
เขียนในรูปแบบ logstash JSON แต่รองรับรูปแบบอื่นเช่นกัน
สามารถเขียนไปยังเอาต์พุตหลายรายการได้
ข้อความบันทึกจะถูกบัฟเฟอร์และส่งใหม่โดยอัตโนมัติหากมีปัญหาในการเชื่อมต่อ
ทำงานร่วมกับ Rails ได้อย่างง่ายดายผ่านการกำหนดค่า
เพิ่มบรรทัดนี้ลงใน Gemfile ของแอปพลิเคชันของคุณ:
gem 'logstash-logger'
แล้วดำเนินการ:
$ bundle
หรือติดตั้งด้วยตัวเองเป็น:
$ gem install logstash-logger
ต้องการ 'logstash-logger'# ค่าเริ่มต้นเป็น UDP บน 0.0.0.0logger = LogStashLogger.new (พอร์ต: 5228)# ระบุโฮสต์และประเภท (UDP หรือ TCP) อย่างชัดเจนudp_logger = LogStashLogger.new (ประเภท: :udp, โฮสต์: 'localhost' , พอร์ต: 5228)tcp_logger = LogStashLogger.new(ประเภท: :tcp, โฮสต์: 'localhost', พอร์ต: 5229)# loggersfile_logger ประเภทอื่น = LogStashLogger.new (ประเภท: :file, เส้นทาง: 'log/development.log', ซิงค์: true) unix_logger = LogStashLogger.new (ประเภท: :unix, เส้นทาง: '/tmp/sock')syslog_logger = LogStashLogger.new(ประเภท: :syslog)redis_logger = LogStashLogger.new(ประเภท: :redis)kafka_logger = LogStashLogger.new(ประเภท: :kafka)stdout_logger = LogStashLogger.new(ประเภท: :stdout)stderr_logger = LogStashLogger.new(ประเภท: :stderr)io_logger = LogStashLogger.new(ประเภท: :io, io: io)# ใช้ formattercee_logger = LogStashLogger.ใหม่( ประเภท: :tcp, โฮสต์: 'logsene-receiver-syslog.sematext.com', พอร์ต: 514, ตัวจัดรูปแบบ: :cee_syslog)custom_formatted_logger = LogStashLogger.new( ประเภท: :สีแดง, ตัวจัดรูปแบบ: MyCustomFormatter)lambda_formatted_logger = LogStashLogger.new( ประเภท: :stdout, ตัวจัดรูปแบบ: ->(ความรุนแรง, เวลา, ชื่อโปรแกรม, msg) { "[#{progname}] #{msg}" })ruby_default_formatter_logger = LogStashLogger.new( ประเภท: :ไฟล์, เส้นทาง: 'log/development.log', formatter: ::Logger::Formatter)# ส่งข้อความไปยังเอาต์พุตหลายตัว แต่ละเอาต์พุตจะมีรูปแบบเดียวกัน # Syslog ไม่สามารถเป็นเอาต์พุตได้เนื่องจากต้องใช้ logger.multi_delegating_logger แยกต่างหาก = LogStashLogger.new( ประเภท: :multi_delegator, เอาท์พุต: [{ ประเภท: :file, เส้นทาง: 'log/development.log' },{ ประเภท: :udp, โฮสต์: 'localhost', พอร์ต: 5228 } ])# ปรับสมดุลข้อความระหว่างเอาต์พุตหลายตัว # ทำงานเหมือนกับผู้มอบหมายหลายราย แต่จะสุ่มเลือกเอาต์พุตเพื่อส่งข้อความแต่ละข้อความ balancer_logger = LogStashLogger.new( ประเภท: :บาลานเซอร์, เอาท์พุต: [{ ประเภท: :udp, โฮสต์: 'host1', พอร์ต: 5228 }, { ประเภท: :udp, โฮสต์: 'host2', พอร์ต: 5228 } ])# ส่งข้อความไปยังตัวบันทึกหลายตัว # ใช้สิ่งนี้หากคุณต้องการส่งรูปแบบที่แตกต่างกันไปยังเอาต์พุตที่แตกต่างกัน # หากคุณต้องการเข้าสู่ระบบ syslog คุณต้องใช้ this.multi_logger = LogStashLogger.new( ประเภท: :multi_logger, เอาท์พุต: [{ ประเภท: :file, เส้นทาง: 'log/development.log', ตัวจัดรูปแบบ: ::Logger::Formatter },{ ประเภท: :tcp, โฮสต์: 'localhost', พอร์ต: 5228, ตัวจัดรูปแบบ: :json } ])# ข้อความต่อไปนี้ถูกเขียนไปยังพอร์ต UDP 5228:logger.info 'test'# {"message": "test","@timestamp":2014-05-22T09:37:19.204-07:00", "@version": "1" "ความรุนแรง" "INFO" "โฮสต์":"[ชื่อโฮสต์]"}logger.error '{"ข้อความ": "ข้อผิดพลาด"}'# {"ข้อความ": "ข้อผิดพลาด" "@timestamp":2014-05-22T10:10:55.877-07:00","@version""1""ความรุนแรง": "ข้อผิดพลาด" "โฮสต์" :"[ชื่อโฮสต์]"}ข้อความ logger.debug: 'ทดสอบ', foo: 'bar'# {"message": "test", "foo": "bar", "@timestamp":2014-05-22T09:43:24.004-07:00","@version":1","ความรุนแรง" :"DEBUG", "host": "[ชื่อโฮสต์]"} logger.warn LogStash::Event.new (ข้อความ: 'ทดสอบ', foo: 'บาร์')# {"message": "test", "foo": "bar", "@timestamp": "2014-05-22T16:44:37.364Z", "@version": "1", "ความรุนแรง": คำเตือน ","host":"[ชื่อโฮสต์]"}# ติดแท็ก logginglogger.tagged('foo') { logger.fatal('bar') }# {"message": "bar", "@timestamp":2014-05-26T20:35:14.685-07:00","@version""1""ความรุนแรง": "FATAL" "โฮสต์" :"[ชื่อโฮสต์]", "แท็ก":["foo"]}
คุณสามารถใช้ URI เพื่อกำหนดค่าเครื่องบันทึก logstash แทนแฮชได้ สิ่งนี้มีประโยชน์ในสภาพแวดล้อมเช่น Heroku ซึ่งคุณอาจต้องการอ่านค่าการกำหนดค่าจากสภาพแวดล้อม รูปแบบ URI คือ type://host:port/path?key=value
ตัวอย่างการกำหนดค่า URI บางส่วนมีดังต่อไปนี้
udp://localhost:5228 tcp://localhost:5229 unix:///tmp/socket file:///path/to/file redis://localhost:6379 kafka://localhost:9092 stdout:/ stderr:/
ส่ง URI ไปยังตัวบันทึก logstash ของคุณดังนี้:
# อ่าน URI จากสภาพแวดล้อม Variablelogger = LogStashLogger.new(uri: ENV['LOGSTASH_URI'])
เพื่อให้ logstash รับและแยกวิเคราะห์เหตุการณ์ได้อย่างถูกต้อง คุณจะต้องกำหนดค่าและเรียกใช้ Listener ที่ใช้ตัวแปลงสัญญาณ json_lines
ตัวอย่างเช่น หากต้องการรับเหตุการณ์ผ่าน UDP บนพอร์ต 5228:
ป้อนข้อมูล { udp {โฮสต์ => "0.0.0.0" พอร์ต => 5228codec => json_lines -
อินพุต File และ Redis ควรใช้ตัวแปลงสัญญาณ json
แทน สำหรับข้อมูลเพิ่มเติม โปรดอ่านเอกสาร Logstash
ดูไดเร็กทอรีตัวอย่างสำหรับตัวอย่างการกำหนดค่าเพิ่มเติม
หากคุณใช้ TCP จะมีตัวเลือกในการเพิ่มใบรับรอง SSL ให้กับตัวเลือกแฮชเมื่อเริ่มต้น
LogStashLogger.new (ประเภท: :tcp พอร์ต: 5228, ssl_certificate: "/path/to/certificate.crt")
สามารถสร้างใบรับรอง SSL และคีย์ได้โดยใช้
openssl req -x509 -batch -nodes -newkey rsa:2048 -keyout logstash.key -out logstash.crt
คุณยังสามารถเปิดใช้งาน SSL ได้โดยไม่ต้องมีใบรับรอง:
LogStashLogger.new (ประเภท: :tcp, พอร์ต: 5228, ssl_enable: true)
ระบุบริบท SSL เพื่อให้สามารถควบคุมลักษณะการทำงานได้มากขึ้น ตัวอย่างเช่น ตั้งค่าโหมดการตรวจสอบ:
ctx = OpenSSL::SSL::SSLContext.newctx.set_params (verify_mode: OpenSSL::SSL::VERIFY_NONE)LogStashLogger.new (ประเภท: :tcp, พอร์ต: 5228, ssl_context: ctx)
จำเป็นต้องมีการกำหนดค่า Logstash ต่อไปนี้สำหรับ SSL:
ป้อนข้อมูล { tcp {โฮสต์ => "0.0.0.0" พอร์ต => 5228codec => json_linesssl_enable => truessl_cert => "/path/to/certificate.crt"ssl_key => "/path/to/key.key" -
การยืนยันชื่อโฮสต์ถูกเปิดใช้งานตามค่าเริ่มต้น หากไม่มีการกำหนดค่าเพิ่มเติม ชื่อโฮสต์ที่มอบให้ :host
จะถูกนำมาใช้เพื่อตรวจสอบข้อมูลประจำตัวใบรับรองของเซิร์ฟเวอร์
หากคุณไม่ส่ง :ssl_context
หรือส่งค่า falsey ไปยังตัวเลือก :verify_hostname
การยืนยันชื่อโฮสต์จะไม่เกิดขึ้น
ตรวจสอบชื่อโฮสต์จากตัวเลือก :host
ctx = OpenSSL::SSL::SSLContext.newctx.cert = '/path/to/cert.pem'ctx.verify_mode = OpenSSL::SSL::VERIFY_PEERLogStashLogger.new ประเภท: :tcp, โฮสต์: 'logstash.example.com' พอร์ต: 5228, ssl_context: ctx
ตรวจสอบชื่อโฮสต์ที่แตกต่างจากตัวเลือก :host
LogStashLogger.ใหม่ ประเภท: :tcp, โฮสต์: '1.2.3.4' พอร์ต: 5228, ssl_context: ctx, Verify_hostname: 'server.example.com'
ปิดการใช้งานการตรวจสอบชื่อโฮสต์อย่างชัดเจน
LogStashLogger.ใหม่ ประเภท: :tcp, โฮสต์: '1.2.3.4' พอร์ต: 5228, ssl_context: ctx, ตรวจสอบ_ชื่อโฮสต์: เท็จ
LogStashLogger
โดยค่าเริ่มต้นจะบันทึกออบเจ็กต์ JSON ด้วยรูปแบบด้านล่าง
{ "message":ข้อความบางส่วน", "@timestamp":2015-01-29T10:43:32.196-05:00", "@version":1", "ความรุนแรง": "INFO", "host" ///ชื่อโฮสต์"}
แอปพลิเคชันบางตัวอาจต้องแนบข้อมูลเมตาเพิ่มเติมลงในแต่ละข้อความ LogStash::Event
สามารถจัดการได้โดยตรงโดยการระบุบล็อก customize_event
ในการกำหนดค่า LogStashLogger
config = LogStashLogger.configure ทำ | config | config.customize_event ทำ |เหตุการณ์|เหตุการณ์["other_field"] = "some_other_value" สิ้นสุด
การกำหนดค่านี้จะส่งผลให้ได้ผลลัพธ์ดังต่อไปนี้
{"ข้อความ": "ข้อความบางส่วน","@timestamp": "2015-01-29T10:43:32.196-05:00","@version": "1", "ความรุนแรง": "INFO", "โฮสต์" ": "ชื่อโฮสต์", "other_field": "some_other_value"}
บล็อกนี้มีสิทธิ์เข้าถึงกิจกรรมโดยสมบูรณ์ ดังนั้นคุณจึงสามารถลบฟิลด์ แก้ไขฟิลด์ที่มีอยู่ ฯลฯ ได้ ตัวอย่างเช่น หากต้องการลบการประทับเวลาเริ่มต้น:
config = LogStashLogger.configure ทำ | config | config.customize_event ทำ | เหตุการณ์ |event.remove('@timestamp') สิ้นสุด
คุณยังสามารถปรับแต่งเหตุการณ์ตามตัวบันทึกโดยส่งอ็อบเจ็กต์ที่สามารถเรียกได้ (แลมบ์ดาหรือ proc) ไปยังตัวเลือก customize_event
เมื่อสร้างตัวบันทึก:
LogStashLogger.new(customize_event: ->(event){ event['other_field'] = 'other_field' })
สำหรับอุปกรณ์ที่สร้างการเชื่อมต่อกับบริการระยะไกล ข้อความบันทึกจะถูกบัฟเฟอร์ภายในและถูกล้างในเธรดพื้นหลัง หากมีปัญหาในการเชื่อมต่อ ข้อความจะถูกเก็บไว้ในบัฟเฟอร์และส่งอีกครั้งโดยอัตโนมัติจนกว่าจะสำเร็จ เอาต์พุตที่รองรับการเขียนเป็นชุด (Redis และ Kafka) จะเขียนข้อความบันทึกจำนวนมากจากบัฟเฟอร์ ฟังก์ชั่นนี้ถูกนำมาใช้โดยใช้ทางแยกของ Stud::Buffer คุณสามารถกำหนดค่าลักษณะการทำงานได้โดยส่งตัวเลือกต่อไปนี้ไปยัง LogStashLogger:
:buffer_max_items - จำนวนรายการสูงสุดที่จะบัฟเฟอร์ก่อนที่จะทำการฟลัช ค่าเริ่มต้นคือ 50
:buffer_max_interval - จำนวนวินาทีสูงสุดที่จะรอระหว่างการฟลัช ค่าเริ่มต้นคือ 5
:drop_messages_on_flush_error - วางข้อความเมื่อมีข้อผิดพลาดในการฟลัช ค่าเริ่มต้นเป็นเท็จ
:drop_messages_on_full_buffer - วางข้อความเมื่อบัฟเฟอร์เต็ม ค่าเริ่มต้นเป็นจริง
:sync - ล้างบัฟเฟอร์ทุกครั้งที่ได้รับข้อความ (บล็อก) ค่าเริ่มต้นเป็นเท็จ
:buffer_flush_at_exit - ล้างข้อความเมื่อออกจากโปรแกรม ค่าเริ่มต้นเป็นจริง
:buffer_logger - Logger เพื่อเขียนบัฟเฟอร์ข้อความดีบัก/ข้อผิดพลาด ไม่มีค่าเริ่มต้น
คุณสามารถปิดการบัฟเฟอร์ได้โดยการตั้งค่า sync = true
โปรดระวังข้อควรระวังต่อไปนี้สำหรับพฤติกรรมนี้:
เป็นไปได้ที่จะมีการส่งข้อความบันทึกซ้ำเมื่อลองอีกครั้ง สำหรับเอาต์พุตเช่น Redis และ Kafka ที่เขียนเป็นชุด สามารถส่งทั้งชุดอีกครั้งได้ หากนี่เป็นปัญหา คุณสามารถเพิ่มฟิลด์ UUID ลงในแต่ละเหตุการณ์เพื่อระบุได้โดยไม่ซ้ำกัน คุณสามารถดำเนินการนี้ได้ในบล็อก customize_event
หรือโดยใช้ตัวกรอง UUID ของ logstash
ยังคงสามารถสูญเสียข้อความบันทึกได้ Ruby จะไม่ตรวจพบปัญหาการเชื่อมต่อ TCP/UDP ในทันที ในการทดสอบของฉัน Ruby ใช้เวลาประมาณ 4 วินาทีเพื่อสังเกตว่าจุดสิ้นสุดการรับหยุดทำงานและเริ่มเพิ่มข้อยกเว้น เนื่องจากผู้ฟัง logstash บน TCP/UDP ไม่รับทราบข้อความที่ได้รับ จึงเป็นไปไม่ได้ที่จะทราบว่าข้อความบันทึกใดที่จะส่งอีกครั้ง
เมื่อปิด sync
Ruby อาจบัฟเฟอร์ข้อมูลภายในก่อนที่จะเขียนไปยังอุปกรณ์ IO นี่คือเหตุผลที่คุณอาจไม่เห็นข้อความที่เขียนลงในซ็อกเก็ต UDP หรือ TCP ในทันที แม้ว่าบัฟเฟอร์ของ LogStashLogger จะถูกล้างเป็นระยะๆ
ตามค่าเริ่มต้น ข้อความจะถูกละทิ้งเมื่อบัฟเฟอร์เต็ม กรณีนี้อาจเกิดขึ้นได้หากแหล่งเอาต์พุตหยุดทำงานนานเกินไปหรือได้รับข้อความบันทึกเร็วเกินไป หากแอปพลิเคชันของคุณหยุดทำงานกะทันหัน (เช่น โดย SIGKILL หรือไฟฟ้าดับ) บัฟเฟอร์ทั้งหมดจะสูญหาย
คุณสามารถทำให้ข้อความสูญหายน้อยลงโดยการเพิ่ม buffer_max_items
(เพื่อให้สามารถจัดกิจกรรมในบัฟเฟอร์ได้มากขึ้น) และลด buffer_max_interval
(เพื่อรอเวลาน้อยลงระหว่างการฟลัช) วิธีนี้จะเพิ่มความกดดันด้านหน่วยความจำให้กับแอปพลิเคชันของคุณเนื่องจากข้อความบันทึกสะสมอยู่ในบัฟเฟอร์ ดังนั้นตรวจสอบให้แน่ใจว่าคุณได้จัดสรรหน่วยความจำเพียงพอให้กับกระบวนการของคุณ
หากคุณไม่ต้องการสูญเสียข้อความเมื่อบัฟเฟอร์เต็ม คุณสามารถตั้งค่า drop_messages_on_full_buffer = false
โปรดทราบว่าหากบัฟเฟอร์เต็ม ข้อความบันทึกขาเข้าใดๆ จะถูกบล็อก ซึ่งอาจไม่พึงประสงค์
เอาต์พุตตัวบันทึกทั้งหมดรองรับการตั้งค่า sync
สิ่งนี้คล้ายคลึงกับการตั้งค่า "โหมดซิงค์" บนออบเจ็กต์ Ruby IO เมื่อตั้งค่าเป็น true
เอาต์พุตจะถูกล้างทันทีและไม่ถูกบัฟเฟอร์ภายใน โดยปกติแล้ว สำหรับอุปกรณ์ที่เชื่อมต่อกับบริการระยะไกล การบัฟเฟอร์เป็นสิ่งที่ดีเนื่องจากจะช่วยปรับปรุงประสิทธิภาพและลดโอกาสที่จะเกิดข้อผิดพลาดที่ส่งผลต่อโปรแกรม สำหรับอุปกรณ์เหล่านี้ sync
ค่าเริ่มต้นเป็น false
และขอแนะนำให้คงค่าเริ่มต้นไว้ คุณอาจต้องการเปิดโหมดการซิงค์สำหรับการทดสอบ เช่น หากคุณต้องการดูข้อความบันทึกทันทีหลังจากที่เขียน
ขอแนะนำให้เปิดโหมดการซิงค์สำหรับไฟล์และเอาต์พุตซ็อกเก็ต Unix เพื่อให้แน่ใจว่าข้อความบันทึกจากเธรดหรือกระบวนการต่างๆ ถูกเขียนอย่างถูกต้องในบรรทัดที่แยกจากกัน
ดู #44 สำหรับรายละเอียดเพิ่มเติม
หากมีข้อยกเว้นเกิดขึ้นขณะเขียนข้อความไปยังอุปกรณ์ ข้อยกเว้นจะถูกบันทึกโดยใช้ตัวบันทึกภายใน ตามค่าเริ่มต้น บันทึกนี้จะไปที่ $stderr คุณสามารถเปลี่ยนตัวบันทึกข้อผิดพลาดได้โดยการตั้งค่า LogStashLogger.configuration.default_error_logger
หรือโดยการส่งอ็อบเจ็กต์ตัวบันทึกของคุณเองในคีย์การกำหนดค่า :error_logger
เมื่อสร้างอินสแตนซ์ LogStashLogger
LogStashLogger ให้การสนับสนุนการปิดเสียงคนตัดไม้สไตล์ Rails การใช้งานถูกดึงมาจาก Rails แต่ไม่มีการขึ้นต่อกัน ดังนั้นจึงสามารถใช้นอกแอป Rails ได้ อินเทอร์เฟซเหมือนกับใน Rails:
logger.silence (temporary_level) ทำ ...จบ
ตามค่าเริ่มต้น LogStashLogger จะสร้างตัวบันทึกที่ขยายคลาส Logger
ในตัวของ Ruby หากคุณต้องการใช้งานตัวบันทึกอื่น คุณสามารถใช้คลาสอื่นได้โดยส่งผ่านคลาสด้วยตัวเลือก logger_class
โปรดทราบว่าสำหรับ syslog จำเป็นต้องมีคลาส Syslog::Logger
และไม่สามารถเปลี่ยนแปลงได้
รองรับ Rails 4.2 และ 5.x
ตามค่าเริ่มต้น ข้อความบันทึก Rails ทุกข้อความจะถูกเขียนไปยัง logstash ในรูปแบบ LogStash::Event
JSON
สำหรับเหตุการณ์ logstash ที่น้อยที่สุดและมีโครงสร้างมากขึ้น ให้ลองใช้หนึ่งในอัญมณีต่อไปนี้:
บันทึก
คนสวน
ขณะนี้ Gem เหล่านี้ส่งออกสตริง JSON ซึ่ง LogStashLogger จากนั้นจะแยกวิเคราะห์ เวอร์ชันในอนาคตของ Gem เหล่านี้อาจมีการผสานรวมที่ลึกซึ้งยิ่งขึ้นกับ LogStashLogger (เช่น โดยการเขียนอ็อบเจ็กต์ LogStash::Event
โดยตรง)
เพิ่มสิ่งต่อไปนี้ใน config/environments/production.rb
ของคุณ :
# ทางเลือก Rails ตั้งค่าเริ่มต้นเป็น :infoconfig.log_level = :debug# ทางเลือก Rails 4 ค่าเริ่มต้นเป็น true ในการพัฒนาและ false ใน Productionconfig.autoflush_log = true# ทางเลือก ให้ใช้ URI เพื่อกำหนดค่า มีประโยชน์บน Herokuconfig.logstash.uri = ENV['LOGSTASH_URI']# ไม่บังคับ ค่าเริ่มต้นเป็น :json_lines หากมีเอาต์พุตหลายรายการ # ทั้งหมดจะใช้ formatter.config.logstash.formatter = :json_lines# ร่วมกัน เป็นทางเลือก ตัวบันทึกสำหรับบันทึกข้อผิดพลาดในการเขียน ค่าเริ่มต้นคือการเข้าสู่ระบบ $stderrconfig.logstash.error_logger = Logger.new($stderr)# ตัวเลือก จำนวนรายการสูงสุดที่จะบัฟเฟอร์ก่อนที่จะทำการฟลัช ค่าเริ่มต้นคือ 50config.logstash.buffer_max_items = 50# ตัวเลือก จำนวนวินาทีสูงสุดที่จะรอระหว่างฟลัช ค่าเริ่มต้นเป็น 5config.logstash.buffer_max_interval = 5# ไม่บังคับ ให้วางข้อความเมื่อเกิดข้อผิดพลาดในการเชื่อมต่อ ค่าเริ่มต้นเป็น falseconfig.logstash.drop_messages_on_flush_error = false# ทางเลือก ให้ปล่อยข้อความเมื่อบัฟเฟอร์เต็ม ค่าเริ่มต้นเป็น trueconfig.logstash.drop_messages_on_full_buffer = true
# ตัวเลือก ค่าเริ่มต้นเป็น '0.0.0.0'config.logstash.host = 'localhost'# ตัวเลือก ค่าเริ่มต้นเป็น :udp.config.logstash.type = :udp# จำเป็น พอร์ตสำหรับเชื่อมต่อ toconfig.logstash.port = 5228
# ไม่บังคับ มีค่าเริ่มต้นเป็น '0.0.0.0'config.logstash.host = 'localhost'# Required พอร์ตสำหรับเชื่อมต่อ toconfig.logstash.port = 5228# Requiredconfig.logstash.type = :tcp# ไม่บังคับ เปิดใช้งาน SSLconfig.logstash ssl_enable = จริง
# Requiredconfig.logstash.type = :unix# Requiredconfig.logstash.path = '/tmp/sock'
หากคุณใช้ Ruby 1.9 ให้เพิ่ม Syslog::Logger
v2 ลงใน Gemfile ของคุณ:
gem 'SyslogLogger', '2.0'
หากคุณใช้ Ruby 2+ Syslog::Logger
จะถูกสร้างขึ้นในไลบรารีมาตรฐานแล้ว
# Requiredconfig.logstash.type = :syslog# ไม่จำเป็น ค่าเริ่มต้นเป็น 'ruby'config.logstash.program_name = 'MyApp'# ระดับสิ่งอำนวยความสะดวกเริ่มต้นที่เป็นตัวเลือก ใช้งานได้เฉพาะใน Ruby 2+config.logstash.facility = Syslog::LOG_LOCAL0
เพิ่มอัญมณี Redis ให้กับ Gemfile ของคุณ:
gem 'redis'
# Requiredconfig.logstash.type = :redis# ตัวเลือก โดยจะใช้ค่าเริ่มต้นเป็น 'logstash' listconfig.logstash.list = 'logstash'# ตัวเลือกอื่นๆ ทั้งหมดจะถูกส่งผ่านไปยังไคลเอนต์ Redis# ตัวเลือกที่รองรับ ได้แก่ โฮสต์ พอร์ต เส้นทาง รหัสผ่าน , url# ตัวอย่าง:# ไม่บังคับ Redis จะใช้ค่าเริ่มต้นเป็น localhostconfig.logstash.host = 'localhost'# ไม่บังคับ Redis จะใช้ค่าเริ่มต้นเป็นพอร์ต 6379config.logstash.port = 6379
เพิ่มอัญมณีโพไซดอนลงใน Gemfile ของคุณ:
gem 'poseidon'
# Requiredconfig.logstash.type = :kafka# ตัวเลือก จะใช้ค่าเริ่มต้นเป็น 'logstash' topicconfig.logstash.path = 'logstash'# ตัวเลือก จะใช้ค่าเริ่มต้นเป็น 'logstash-logger' Producerconfig.logstash.producer = 'logstash-logger '# ตัวเลือก จะใช้ค่าเริ่มต้นเป็น localhost:9092 host/portconfig.logstash.hosts = ['localhost:9092']# ตัวเลือก จะใช้ค่าเริ่มต้นเป็น 1 วินาที backoffconfig.logstash.backoff = 1
เพิ่ม aws-sdk gem ลงใน Gemfile ของคุณ:
# aws-sdk >= 3.0 gem 'aws-sdk-kinesis' # aws-sdk < 3.0 gem 'aws-sdk'
# Requiredconfig.logstash.type = :kinesis# ตัวเลือก จะใช้ค่าเริ่มต้นเป็น 'logstash' streamconfig.logstash.stream = 'my-stream-name'# ตัวเลือก จะใช้ค่าเริ่มต้นเป็น 'us-east-1'config.logstash.aws_region = 'us-west-2'# ตัวเลือก จะใช้ค่าเริ่มต้นเป็นสภาพแวดล้อม AWS_ACCESS_KEY_ID Variableconfig.logstash.aws_access_key_id = 'ASKASKHLD12341'# ตัวเลือก จะมีค่าเริ่มต้นเป็นตัวแปรสภาพแวดล้อม AWS_SECRET_ACCESS_KEY configuration.logstash.aws_secret_access_key = 'ASKASKHLD1234123412341234'
เพิ่ม aws-sdk gem ลงใน Gemfile ของคุณ:
# aws-sdk >= 3.0 gem 'aws-sdk-firehose' # aws-sdk < 3.0 gem 'aws-sdk'
# Requiredconfig.logstash.type = :firehose# ตัวเลือก จะใช้ค่าเริ่มต้นเป็นการจัดส่ง 'logstash' streamconfig.logstash.stream = 'my-stream-name'# ไม่บังคับ จะใช้ค่าเริ่มต้นเป็นการกำหนดค่าภูมิภาคเริ่มต้นของ AWS chainconfig.logstash.aws_region = ' us-west-2'# ไม่บังคับ จะใช้ค่าเริ่มต้นเป็นผู้ให้บริการข้อมูลรับรองเริ่มต้นของ AWS chainconfig.logstash.aws_access_key_id = 'ASKASKHLD12341'# ไม่บังคับ จะใช้ค่าเริ่มต้นเป็นผู้ให้บริการข้อมูลประจำตัวเริ่มต้นของ AWS chainconfig.logstash.aws_secret_access_key = 'ASKASKHLD1234123412341234'
# Requiredconfig.logstash.type = :file# ตัวเลือก ค่าเริ่มต้นเป็นบันทึก Rails pathconfig.logstash.path = 'log/production.log'
# Requiredconfig.logstash.type = :io# Requiredconfig.logstash.io = io
# Requiredconfig.logstash.type = :multi_delegator# Requiredconfig.logstash.outputs = [ {ประเภท: :file,เส้นทาง: 'log/production.log' - {ประเภท: :udp พอร์ต: 5228 โฮสต์: 'localhost' -
# Requiredconfig.logstash.type = :multi_logger# จำเป็น ตัวบันทึกแต่ละตัวอาจมี formatter.config.logstash.outputs = [ {ประเภท: :file,เส้นทาง: 'log/production.log',ตัวจัดรูปแบบ: ::Logger::Formatter - {ประเภท: :udp พอร์ต: 5228 โฮสต์: 'localhost' -
ในเว็บแอปพลิเคชัน คุณสามารถบันทึกข้อมูลจากคำขอ HTTP (เช่น ส่วนหัว) โดยใช้มิดเดิลแวร์ RequestStore ตัวอย่างต่อไปนี้ถือว่า Rails
# ใน Gemfilegem 'request_store'
# ใน application.rbLogStashLogger.configure ทำ | config | config.customize_event ทำ |เหตุการณ์|เหตุการณ์["session_id"] = RequestStore.store[:load_balancer_session_id] สิ้นสุด
# ในแอป/คอนโทรลเลอร์/application_controller.rbbefore_filter :track_load_balancer_session_iddef track_load_balancer_session_id RequestStore.store[:load_balancer_session_id] = request.headers["X-LOADBALANCER-SESSIONID"]end
หากแอปพลิเคชันของคุณแยก (ตามปกติในเว็บเซิร์ฟเวอร์หลายแห่ง) คุณจะต้องจัดการการล้างทรัพยากรบนอินสแตนซ์ LogStashLogger ของคุณ วิธีการอินสแตนซ์ #reset
ใช้เพื่อจุดประสงค์นี้ นี่คือตัวอย่างการกำหนดค่าสำหรับเว็บเซิร์ฟเวอร์ทั่วไปหลายตัวที่ใช้กับ Rails:
ผู้โดยสาร:
::PhusionPassenger.on_event(:starting_worker_process) ทำ |forked| Rails.logger.รีเซ็ตสิ้นสุด
เสือพูมา:
# ใน config/puma.rbon_worker_boot ให้ทำ Rails.logger.รีเซ็ตสิ้นสุด
ยูนิคอร์น
# ใน config/unicorn.rbafter_fork ทำ | เซิร์ฟเวอร์ ผู้ปฏิบัติงาน | Rails.logger.รีเซ็ตสิ้นสุด
ได้รับการยืนยันว่าจะทำงานร่วมกับ:
MRI รูบี้ 2.2 - 2.5
JRuby 9.x
รูบิเนียส
Ruby เวอร์ชัน < 2.2 เป็น EOL'ed และไม่รองรับอีกต่อไป
ขึ้นอยู่กับความต้องการเฉพาะของคุณ แต่แอปพลิเคชันส่วนใหญ่ควรใช้ค่าเริ่มต้น (UDP) ข้อดีและข้อเสียของแต่ละประเภทมีดังนี้
UDP เร็วกว่า TCP เนื่องจากเป็นแบบอะซิงโครนัส (ไฟแล้วลืม) อย่างไรก็ตาม นี่หมายความว่าข้อความบันทึกอาจถูกทิ้ง นี่เป็นเรื่องปกติสำหรับหลาย ๆ แอปพลิเคชัน
TCP ตรวจสอบว่าทุกข้อความได้รับผ่านการสื่อสารสองทาง นอกจากนี้ยังรองรับ SSL สำหรับการส่งข้อความบันทึกผ่านเครือข่ายอย่างปลอดภัย การดำเนินการนี้อาจทำให้แอปของคุณช้าลงจนถึงการรวบรวมข้อมูลหากตัวฟัง TCP มีภาระงานหนัก
ไฟล์นี้ใช้งานง่าย แต่คุณจะต้องกังวลเกี่ยวกับการหมุนเวียนบันทึกและพื้นที่ดิสก์ไม่เพียงพอ
การเขียนไปยังซ็อกเก็ต Unix นั้นเร็วกว่าการเขียนไปยังพอร์ต TCP หรือ UDP แต่ใช้งานได้เฉพาะในเครื่องเท่านั้น
การเขียนไปยัง Redis นั้นดีสำหรับการตั้งค่าแบบกระจายที่สร้างบันทึกจำนวนมาก อย่างไรก็ตาม คุณจะมีอีกส่วนหนึ่งที่เคลื่อนไหวได้และต้องกังวลว่า Redis หน่วยความจำจะหมด
แนะนำให้เขียนถึง stdout เพื่อวัตถุประสงค์ในการแก้ไขจุดบกพร่องเท่านั้น
สำหรับการอภิปรายโดยละเอียดเพิ่มเติมเกี่ยวกับ UDP กับ TCP ฉันแนะนำให้อ่านบทความนี้: UDP กับ TCP
หากคุณกำลังใช้อุปกรณ์ที่สนับสนุนโดยอ็อบเจ็กต์ Ruby IO (เช่น ไฟล์ ซ็อกเก็ต UDP หรือซ็อกเก็ต TCP) โปรดทราบว่า Ruby จะเก็บบัฟเฟอร์ภายในของตัวเองไว้ แม้ว่า LogStashLogger จะบัฟเฟอร์ข้อความและฟลัชข้อความเป็นระยะ แต่ข้อมูลที่เขียนไปยังออบเจ็กต์ IO สามารถบัฟเฟอร์โดย Ruby ภายในได้อย่างไม่มีกำหนด และอาจไม่สามารถเขียนได้จนกว่าโปรแกรมจะยุติการทำงาน หากสิ่งนี้รบกวนจิตใจคุณหรือคุณจำเป็นต้องดูข้อความบันทึกทันที ทางเลือกเดียวของคุณคือตั้งค่าตัวเลือก sync: true
แอปพลิเคชันของคุณอาจพยายามบันทึกข้อมูลที่ไม่ได้เข้ารหัสด้วยวิธีที่ถูกต้อง เมื่อสิ่งนี้เกิดขึ้น ไลบรารี JSON มาตรฐานของ Ruby จะทำให้เกิดข้อยกเว้น คุณอาจสามารถเอาชนะสิ่งนี้ได้ด้วยการสลับตัวเข้ารหัส JSON อื่นเช่น Oj ใช้ oj_mimic_json gem เพื่อใช้ Oj สำหรับการสร้าง JSON
Heroku แนะนำให้ติดตั้ง rails_12factor เพื่อให้บันทึกถูกส่งไปยัง STDOUT น่าเสียดายที่การดำเนินการนี้จะแทนที่ LogStashLogger ซึ่งทำให้บันทึกไม่ถูกส่งไปยังปลายทางที่กำหนดค่าไว้ วิธีแก้ไขคือการลบ rails_12factor
ออกจาก Gemfile ของคุณ
นี่น่าจะไม่ใช่ปัญหากับ LogStashLogger แต่เป็นอัญมณีอื่นที่เปลี่ยนระดับบันทึกของ Rails.logger
กรณีนี้อาจเป็นไปได้โดยเฉพาะอย่างยิ่งหากคุณใช้เซิร์ฟเวอร์แบบเธรด เช่น Puma เนื่องจาก Gem มักจะเปลี่ยนระดับบันทึกของ Rails.logger
ด้วยวิธีที่ไม่ปลอดภัยสำหรับเธรด ดู #17 สำหรับข้อมูลเพิ่มเติม
หากคุณกำลังใช้เอาต์พุต UDP และเขียนไปยัง Listener Logstash คุณน่าจะพบจุดบกพร่องในการใช้งาน UDP ของ Logstash Listener ขณะนี้ยังไม่มีการแก้ไขที่ทราบ ดู #43 สำหรับข้อมูลเพิ่มเติม
ข้อเสียเปรียบที่ทราบของการใช้ TCP หรือ UDP คือขีดจำกัด 65535 ไบต์ของขนาดข้อความทั้งหมด เมื่อต้องการแก้ไขปัญหานี้ คุณจะต้องตัดทอนข้อความโดยการตั้งค่าขนาดข้อความสูงสุด:
LogStashLogger.configure ทำ | config | config.max_message_size = 2000สิ้นสุด
สิ่งนี้จะตัดทอนเฉพาะฟิลด์ message
ของเหตุการณ์ LogStash ดังนั้น ตรวจสอบให้แน่ใจว่าคุณตั้งค่าขนาดข้อความสูงสุดให้น้อยกว่า 65535 ไบต์อย่างมาก เพื่อให้มีที่ว่างสำหรับฟิลด์อื่นๆ
Rails 3.2, MRI Ruby < 2.2 และ JRuby 1.7 ไม่ได้รับการสนับสนุนอีกต่อไป เนื่องจากเป็น EOL'ed หากคุณใช้ Ruby เวอร์ชันเก่า คุณจะต้องใช้ 0.24 หรือต่ำกว่า
คีย์เหตุการณ์ source
ถูกแทนที่ด้วย host
เพื่อให้ตรงกับ Logstash ล่าสุดมากขึ้น
ตัวสร้าง (host, port, type)
เลิกใช้แล้วเพื่อสนับสนุนตัวสร้างแฮชตัวเลือก
LogStash::Event
ใช้รูปแบบ v1 โดยเริ่มต้นเวอร์ชัน 1.2 ขึ้นไป หากคุณใช้ v1 คุณจะต้องติดตั้ง LogStashLogger เวอร์ชัน 0.4+ สิ่งนี้เข้ากันไม่ได้กับ LogStash::Event
v1.1.5 รุ่นเก่าซึ่งใช้รูปแบบ v0
Gem นี้เวอร์ชันก่อนหน้า (<= 0.2.1) ใช้การเชื่อมต่อ TCP เท่านั้น เวอร์ชันที่ใหม่กว่า (>= 0.3) ยังใช้ UDP และใช้เป็นค่าเริ่มต้นใหม่ โปรดทราบว่าหากคุณใช้ตัวสร้างเริ่มต้นและยังคงต้องการ TCP คุณควรเพิ่มอาร์กิวเมนต์เพิ่มเติม:
# ตอนนี้ใช้ค่าเริ่มต้นเป็น UDP แทนที่จะเป็น TCPlogger = LogStashLogger.new('localhost', 5228)# ระบุ TCP อย่างชัดเจนแทน UDPlogger = LogStashLogger.new('localhost', 5228, :tcp)
เดวิด บัตเลอร์
pctj101
แกรี่ เรนนี่
นิค อีเธอร์
อารอน เมบรีย์
ยาน ชูลเต้
เคิร์ต เพรสตัน
คริส แบลทช์ลีย์
เฟลิกซ์ เบคชไตน์
วาดิม คาซาคอฟ
อนิล เรมทุลลา
นิกิต้า โวโรเบ
นักดับเพลิง1919
ไมค์ กันเดอร์ลอย
วิตาลี โกโรเดตสกี้
คอร์ตแลนด์ คาลด์เวลล์
บีเบค เชรษฐา
อเล็กซ์ เอียนัส
เคร็กอ่าน
กลาสซิก
บินลาน
เจา เฟอร์นานเดส
เจ๋งเอลวิส
เซอร์เกย์ เปียนคอฟ
อเล็ก ฮอย
อเล็กเซย์ คราสโนเปรอฟ
กาเบรียล เด โอลิเวร่า
วลาดิสลาฟ ซยาบรูค
มาตุส วาคูลา
ส้อมมัน
สร้างสาขาคุณลักษณะของคุณ ( git checkout -b my-new-feature
)
ยอมรับการเปลี่ยนแปลงของคุณ ( git commit -am 'Add some feature'
)
ผลักดันไปที่สาขา ( git push origin my-new-feature
)
สร้างคำขอดึงใหม่