Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Cơ Sở Dữ Liệu

Tinh giản ghi nhật ký đám mây kết hợp với Fluentd và ObjectRocket

Bài viết này được cùng soạn thảo bởi Hart Hoover và Ryan Walker

Gần đây, đội ngũ DevOps Automation của Rackspace đã công bố một dịch vụ gửi cảnh báo từ New Relic đến bộ phận hỗ trợ của Rackspace. Các cảnh báo này sẽ tạo ticket cho các kỹ sư DevOps của chúng tôi phản hồi, giúp khách hàng yên tâm ngủ ngon khi cảnh báo được tạo lúc 3 giờ sáng. Khi kết hợp với các điểm dữ liệu khác được thu thập về môi trường của khách hàng, các kỹ sư của chúng tôi sẽ xác định vị trí vấn đề và thực hiện phương án xử lý phù hợp.

Trong khi thiết kế hạ tầng cho dịch vụ này, chúng tôi gặp phải một vấn đề phổ biến nhưng thú vị: cần hạn chế truy cập vào các hệ thống nội bộ của Rackspace vì lý do bảo mật, đồng thời vẫn phải duy trì một endpoint công khai để New Relic có thể giao tiếp. Giải pháp của chúng tôi là thiết kế một dịch vụ với các endpoint API công khai và các worker riêng biệt hoàn toàn tách biệt. Các endpoint API công khai nhận cảnh báo từ New Relic và chuyển chúng đến một instance Redis của ObjectRocket đóng vai trò hàng đợi. Các dịch vụ worker chạy nội bộ phía sau tường lửa RackConnect và kéo tin nhắn từ hàng đợi để tạo cảnh báo.

Cách phân vùng môi trường này rất hiệu quả, nhưng tạo ra một vấn đề về tập trung nhật ký (log aggregation). Chúng tôi chạy một stack ElasticSearch/Kibana bên trong môi trường riêng tư. Phía sau tường lửa, chúng tôi dùng fluentd để đẩy nhật ký trực tiếp đến ElasticSearch. Bên ngoài tường lửa, stack EK không thể truy cập được. Để giải quyết, chúng tôi bắt đầu dùng fluentd để đẩy nhật ký từ các dịch vụ API công khai đến một instance MongoDB của ObjectRocket. Bên trong, chúng tôi lại dùng fluentd để kéo nhật ký từ ObjectRocket vào ElasticSearch. Điều này cho chúng tôi một đích đến duy nhất cho tất cả hoạt động của môi trường.

Fluentd là gì?

Fluentd là một trình thu thập dữ liệu mã nguồn mở cố gắng cấu trúc hóa dữ liệu thành JSON nhiều nhất có thể. Điều này có nghĩa là bạn không phải viết và duy trì một đống script để đưa dữ liệu nhật ký vào định dạng tương tự. Tất cả đều là JSON.

Sức mạnh của fluentd nằm ở sự hỗ trợ nhiều nguồn và đích đến. Ví dụ, bạn có thể thu thập dữ liệu từ luồng Twitter và thông báo về nó qua IRC. Có hàng chục plugin cộng đồng sẵn có.

Sử dụng Fluentd với Docker

Sử dụng plugin MongoDB của fluentd, người ta có thể dễ dàng đẩy nhật ký vào ObjectRocket. Trước tiên, các nguồn phải được định nghĩa. Vì tất cả dịch vụ của chúng tôi dùng Docker, chúng tôi phải đưa nhật ký container vào fluentd. Có một bài viết hay bổ sung cho bài này về cách thực hiện tập trung nhật ký với docker-gen và fluentd của Jason Wilder tại đây. Khi container fluentd đang chạy (và docker-gen đã tạo cấu hình fluentd), bạn nên có một phần như sau cho mỗi container đang chạy:

<source> type tail format json time_key time path /var/lib/docker/containers/abcdef/abcdef-json.log pos_file /var/lib/docker/containers/abcdef/abcdef-json.log.pos tag docker.container.abcdef rotate_wait 5 </source>

Đoạn này theo dõi nhật ký container, và theo dõi vị trí trong nhật ký bằng file position. Quan trọng lưu ý rằng tag trong phần cấu hình này là tag fluentd, dùng để báo cho fluentd biết phải làm gì với dữ liệu nó tổng hợp.

Sử dụng Fluentd với MongoDB

Ở phía công khai, chúng tôi báo cho fluentd biết xử lý dữ liệu như thế nào với một "match". Trong trường hợp này, thay thế các biến bằng thông tin thực tế từ cơ sở dữ liệu ObjectRocket của bạn trong cùng file cấu hình:

<match docker.**> type mongo database $DBNAME collection prod host $HOSTNAME port $PORT ssl capped capped_size 100m user $MONGOUSER password $MONGOPASS include_tag_key true </match>

Cài đặt include_tag_key yêu cầu fluentd đưa tag vào bản ghi nhật ký trong MongoDB. Như vậy chúng tôi biết chính xác mục nhật ký nào thuộc container nào. Fluentd sẽ bắt đầu điền dữ liệu vào MongoDB, sau đó chúng tôi kéo về phía riêng tư của ứng dụng.

Ở phía riêng tư, chúng tôi vẫn dùng plugin MongoDB của fluentd, nhưng lần này đặt làm source:

<source> type mongo_tail database $DBNAME collection prod host $HOSTNAME port $PORT user $MONGOUSER password $MONGOPASS ssl time_key time wait_time 5 tag prod id_store_file /app/prod_last_id </source>

Sau đó, chúng tôi cung cấp một "match" cho nhật ký để đẩy chúng vào ElasticSearch:

<match **> type forest subtype elasticsearch <template> host elasticsearch.domain.com port 9200 index_name fluentd logstash_format true buffer_type memory type_name ${tag} flush_interval 3 retry_limit 17 retry_wait 1.0 num_threads 1 </template> </match>

Chúng tôi cũng dùng plugin forest của fluentd giúp đơn giản hóa cấu hình tagging trên nhiều môi trường.

Fluentd là một cách tuyệt vời để tổng hợp nhật ký Docker trên nhiều host và đẩy chúng vào cơ sở dữ liệu MongoDB. Trong trường hợp của chúng tôi, ObjectRocket đóng vai trò trạm trung chuyển giữa môi trường công khai và riêng tư cho việc tập trung nhật ký. Các trường hợp sử dụng khác có thể bao gồm phân tích thời gian thực trên dữ liệu bạn thu thập. Phần tốt nhất cho đội ngũ của chúng tôi là không phải quản lý MongoDB, nhờ độ tin cậy và chuyên môn của ObjectRocket.