Ghi nhật ký kết quả của Daemon với Upstart


34

Tôi có một trình nền tùy chỉnh được quản lý bởi người mới bắt đầu trên máy chủ Ubuntu của tôi. Nó hoạt động hoàn hảo ngoại trừ việc tôi cần nắm bắt (ghi) đầu ra của daemon. Các trang dưới dạng thơ chính thức nói rằng tôi có thể sử dụng console loggedđể làm điều này, nhưng những gì tập tin nào đó đăng nhập vào?

Tôi cũng đã đọc mà console loggedkhông còn là một câu kệ hợp lệ . Tôi hiện đang sử dụng 0.3.9 (Hardy) nhưng sẽ nâng cấp lên 0.6.x (Lucid) sau vài tháng nữa. Nếu console loggedtrên thực tế sẽ không hoạt động với các phiên bản sau, tôi sẽ sử dụng cái gì thay thế?


1
Bạn có thể chỉ cần cập nhật daemon tùy chỉnh của mình để gửi đầu ra tới syslog hoặc tới một logfile được chỉ định trong tệp cấu hình của daemon không?
Zoredache

Câu trả lời:


35

Đoạn mã này sẽ chuyển đầu ra của dịch vụ của bạn vào logger, trong khi vẫn cho phép bạn thực hiện quy trình dịch vụ (do đó thay thế quy trình shell) để việc khởi động không bị nhầm lẫn. Nó cũng đảm bảo rằng quy trình logger được sửa chữa thành init, vì vậy nó không phải là con của dịch vụ của bạn và nó tránh để lại hành trình ngồi trong hệ thống tập tin, mặc dù nó cần tạm thời tạo ra một fifo.

script
  mkfifo /tmp/myservice-log-fifo
  ( logger -t myservice </tmp/myservice-log-fifo & )
  exec >/tmp/myservice-log-fifo
  rm /tmp/myservice-log-fifo
  exec myservice 2>/dev/null
end script

Đây là cách nó hoạt động:

  1. mkfifo /tmp/myservice-log-fifochỉ đơn giản là làm cho tập tin fifo đặc biệt (còn gọi là ống). Nhập man 7 fifođể biết thêm.
  2. ( logger ... </tmp/myservice-log-fifo & ) bắt đầu đọc logger từ fifo, trong nền. Các parens làm cho quá trình logger được sửa chữa thành init, thay vì vẫn là một phần tử con của quy trình shell hiện tại.
  3. exec >/tmp/myservice-log-fifochuyển hướng thiết bị xuất hiện của shell hiện tại đến fifo. Bây giờ chúng tôi có một bộ mô tả tệp mở cho fifo đó và chúng tôi thực sự không cần mục hệ thống tập tin nữa ...
  4. rm /tmp/myservice-log-fifo vì vậy chúng tôi sẽ loại bỏ nó.
  5. exec myservice 2>/dev/nullchỉ đơn giản là chạy dịch vụ theo cách thông thường. Stdout đã đến fifo và điều đó sẽ không thay đổi khi chương trình mới thực thi.

CẬP NHẬT: set -e không cần thiết vì Upstart chạy các tập lệnh với tùy chọn này theo mặc định (xem http://upstart.ubfox.com/cookbook/#develop-scripts-USE-bin-sh )


câu trả lời tuyệt vời, và không để lại fifo tập tin nằm ở bất cứ đâu.
Ash Berlin-Taylor

Là gì set -e?
Peter Mounce

1
Các set -enguyên nhân kịch bản để thoát ngay lập tức nếu bất kỳ lệnh thất bại. Không có dòng đó, tập lệnh sẽ tiếp tục chạy các lệnh tiếp theo một cách vô ích (và có thể nguy hiểm).
Keith Rarick

1
Để đăng nhập stderr cũng như thiết bị xuất chuẩn, hãy thêm dòng exec 2>&1phía trên rmdòng và xóa dòng 2>/dev/nullkhỏi dòng cuối cùng.
itadok

31

Đối với các phiên bản Ubuntu gần đây (12.04+), chỉ cần sử dụng

console log

Và đầu ra daemon (STDOUT & STDERR) sẽ được thêm vào /var/log/upstart/<service>.log

http://upstart.ubfox.com/cookbook/#console-log


2
Điều đó sẽ sạch sẽ và tốt đẹp, nhưng thật không may, nó không hoạt động trên CentOS 6.x vẫn cung cấp một phiên bản cổ điển mới nổi không hỗ trợ điều này.
Cristian Măgherușan-Stanciu

11

Nếu bạn sử dụng khổ console output thơ , sau đó chuyển đầu ra của tập lệnh sang logger(giao diện lệnh shell sang mô đun nhật ký hệ thống syslog (3)) thì nó sẽ hoạt động.

Ví dụ

console output
exec /my/script | logger

sẽ đăng nhập vào /var/log/messages

Ví dụ

console output
exec /my/script | logger -t my-script

sẽ đăng nhập /var/log/messagesvà gắn thẻ từng tin nhắn vớimy-script

logger --help cho các tùy chọn sử dụng logger.

(Tôi đang sử dụng Amazon Linux AMI, dựa trên Centos 5.x; YMMV)


4
Hóa ra đây không phải là một giải pháp tốt. bắt đầu chốt vào PID của logger, không phải của quá trình bạn thực sự muốn nó quản lý.
Peter Mounce

10

Tôi đã không có được mkfifománh khóe để làm việc thỏa đáng; nó dường như không bắt được stderr và cố gắng chuyển hướng khiến Upstart không được bảo lãnh.

Nó cũng có một tác dụng phụ đáng tiếc là làm cho loggerquá trình này bị xáo trộn khi còn nhỏ init, vì vậy thông tin về người "sở hữu" logger bị mất và bất kỳ ai cũng không biết mkfiforằng đó có thể là một quá trình nguy hiểm có thể bị giết.

Thay vào đó tôi đã kết thúc với giải pháp sau đây, giải quyết tất cả các vấn đề này. Nó gây ra logger trở thành một quá trình con, trong khi bảo tồn dịch vụ như là quá trình gốc. Thật không may, nó đòi hỏi phải thực thi bash, nhưng nó trông có vẻ bẩn.

script
  # ... setup commands here, e.g. environment, cd, ...
  exec bash <<EOT
    exec 1> >(logger -t myservice) 2>&1
    exec myservice
EOT
end script

Điều này sử dụng một thủ thuật chuyển hướng stdout và stderr thành một lệnh. Vì chúng tôi thực thi dịch vụ bên trong bashlệnh, điều này có tác dụng phụ là thay thế vỏ và làm cho phép bash trở thành một quy trình con của dịch vụ, như được hiển thị bởi ps aufxw:

myservice 
 \_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
    \_ logger -t myservice

Vì một số lý do, lệnh trên phải được gói trong a bash -c. Tôi cho rằng điều này là do Upstart chỉ giả vờ chạy tập lệnh của bạn thông qua Bash, nhưng thực tế không phải vậy. Nếu bất cứ ai có thể đề xuất một cách để tránh vỏ bash thêm, đó sẽ là tuyệt vời.


1
Vâng! Tôi rất vui vì tôi đã tìm thấy điều này. Có vẻ tốt hơn so với biến thể mkfifo và trong trường hợp của tôi, tôi cần để exec bash -l << EOFkhông mất mát ở đó.
thom_nic

6

Điều này là xấu xí nhưng cho đến nay là tốt nhất tôi đã tìm thấy

thực thi / đường dẫn / đến / máy chủ >> /tmp/upstart.log 2> & 1


2
Giải pháp không tốt khi nói đến xoay vòng nhật ký, vì ứng dụng đang đăng nhập trực tiếp vào tệp. Đăng nhập thông qua syslog tránh các vấn đề liên quan.
Mark Stosberg

3

Bạn cũng có thể chuyển hướng đầu ra sang syslog, vd

exec $SERVER 2>&1 | logger -t myservice -p local0.info

Tuy nhiên, đường ống dẫn có thể gây ra sự khởi đầu để nhầm lẫn giữa quy trình ghi nhật ký với quy trình ghi của daemon.


Các daemon gây nhầm lẫn cho PID thực sự là một daemon vô dụng, vì nó được cho là để xem quá trình, sau đó hồi sinh nó. Bất cứ ý tưởng nào về cách đảm bảo đúng PID đang được theo dõi?
Johann Philipp Strathausen

Tôi nghĩ (nhưng chưa thử) rằng bạn sẽ muốn expect forkhoặc khổ expect daemonthơ. Hoặc bạn có thể cattập tin pid vào thông điệp tường trình, tôi đoán vậy.
Peter Mounce

1

Một cách khác là sử dụng tee như:

exec $SERVER 2>&1 | tee /dev/stderr | logger -t myservice

để có được cả tệp khởi động và đầu ra syslog

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.