2009-03-20 8 views
14

Tôi đang lập kế hoạch gói OpenTibia Server cho Debian. Một trong những điều tôi muốn làm là thêm khởi động qua /etc/init.d và daemonization của quy trình otserv.Chuyển hướng đầu ra tiêu chuẩn sang syslog

Thing, có lẽ chúng ta nên chuyển hướng đầu ra tới syslog. Việc này thường được thực hiện thông qua chức năng syslog(). Hiện nay, các mã được swarmed với:

std::cout << "Stuff to printout" << std::endl; 

Có một cách thích hợp, dễ dàng để thêm, để chuyển hướng đầu ra tiêu chuẩn và đầu ra sai số chuẩn vào syslog mà không thay thế mỗi đơn "gọi" để std :: cout và bạn bè?

Trả lời

4

Không chắc liệu một "C" thẳng câu trả lời cũng đủ; nhưng trong "C" bạn có thể sử dụng các tính năng cơ bản của stdio để cắm (FILE *) trực tiếp vào các cuộc gọi syslog, mà không cần quá trình "logger" can thiệp. Hãy xem http://mischasan.wordpress.com/2011/05/25/redirecting-stderr-to-syslog/

+1

Đây là nó. Nó sẽ là tuyệt vời nếu bạn sẽ dán các phần của bài viết của bạn ở đây, quá;) –

+1

nó hầu như không xách tay, và nó không phải là tiêu chuẩn POSIX – Alnitak

+0

@Ivan: dán một liên kết nhanh hơn so với dán một bài báo. Tôi không kiếm được doanh thu từ việc bạn nhấp vào liên kết blog của tôi :-) – Mischa

2

Hãy thử gói thực thi nhị phân bằng tập lệnh phù hợp, chỉ đọc stdout và stderr và gửi mọi dữ liệu đọc từ chúng bằng cách sử dụng syslog(). Điều đó sẽ hoạt động mà không có bất kỳ thay đổi mã nào trong ứng dụng được bao bọc và khá dễ dàng.

Không chắc chắn liệu có tập lệnh hiện có nào được đưa vào hay không, nhưng viết một tập lệnh không nên khó nếu không.

+0

có vẻ như là giải pháp rất di động, do đó điều này sẽ chỉ cho phép chúng tôi có hai lỗi ở mức nhật ký và thông tin, nhật ký hệ thống linux có nhiều loglevels hơn. Nhưng nếu chúng ta có thể chịu được nhược điểm nhỏ này, đây là một bài đăng cho thấy cách thực hiện điều đó: http://unix.stackexchange.com/questions/124455/linux-how-to-redirect-stdout-stderr-to-logger –

21

Bạn có thể đường ống của bạn stdout-syslog với logger lệnh:

TÊN

logger - a shell command interface to the syslog(3) system log module 

SYNOPSIS

logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message ...] 

MÔ TẢ

Logger makes entries in the system log. It provides a shell command 
interface to the syslog(3) system log module. 

Nếu bạn không cung cấp một thông điệp trên dòng lệnh nó đọc stdin

5

Bạn có thể chuyển hướng bất kỳ dòng trong C++ thông qua rdbuf() lệnh. Đây là một chút phức tạp để thực hiện nhưng không phải là khó khăn.

Bạn cần phải viết một streambuf sẽ xuất ra syslog trên tràn(), và thay thế std :: cout rdbuf bằng streambuf của bạn.

Một ví dụ, mà có đầu ra vào một tập tin (không xử lý lỗi, mã chưa được kiểm tra)

#include <iostream> 
#include <fstream> 
using namespace std; 

int main (int argc, char** argv) { 
    streambuf * yourStreamBuffer = NULL; 
    ofstream outputFileStream; 
    outputFileStream.open ("theOutputFile.txt"); 

    yourStreamBuffer = outputFileStream.rdbuf(); 
    cout.rdbuf(yourStreamBuffer); 

    cout << "Ends up in the file, not std::cout!"; 

    outputFileStream.close(); 

    return 0; 
} 
+0

Hầu như những gì tôi đang tìm kiếm, tuy nhiên, "logger" cung cấp cho tôi thêm thông tin, đặc biệt là nếu tôi chỉ đơn giản là tạo ra một kịch bản bash wrapper. Tuy nhiên, cảm ơn thông tin, và tôi xin lỗi tôi không thể đánh dấu cả hai câu trả lời là Câu trả lời (tm). –

1

tôi chỉ viết một số mã mà sẽ làm điều này. Đó là sử dụng ASL thay vì syslog, và nó sử dụng kevents, vì vậy bạn có thể cần đến cổng nó để các API khác nhau cho hệ thống của bạn (syslog thay vì ASL và bình chọn/chọn thay vì kevent)

http://cgit.freedesktop.org/xorg/app/xinit/tree/launchd/console_redirect.c

Hơn nữa, tôi về cơ bản đã thêm điều này vào libsystem_asl trên Mountain Lion. Kiểm tra trang người dùng cho asl_log_descriptor.

Ví dụ:

#include <asl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main() { 
    asl_log_descriptor(NULL, NULL, ASL_LEVEL_INFO, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE); 
    asl_log_descriptor(NULL, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE); 
    fprintf(stdout, "This is written to stdout which will be at log level info."); 
    fprintf(stderr, "This is written to stderr which will be at log level notice."); 
    return 0; 
}