如何将systemd服务的输出重定向到文件

时间:2016-06-02 07:51:46

标签: linux rhel systemd rhel7

我正在尝试将系统服务的o / p重定向到文件,但它似乎无法正常工作。我这样做:

[Unit]
Description=customprocess
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/binary1 agent -config-dir /etc/sample.d/server
StandardOutput=/var/log1.log
StandardError=/var/log2.log
Restart=always

[Install]
WantedBy=multi-user.target

请建议将o / p重定向到文件的正确方法

8 个答案:

答案 0 :(得分:160)

我认为有一种更优雅的方法可以解决问题:使用标识符将stdout / stderr发送到syslog,并指示您的syslog管理器按程序名称拆分其输出。

在systemd服务单元文件中使用以下属性:

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=<your program identifier> # without any quote

然后,假设您的发行版使用rsyslog来管理系统日志,请在/etc/rsyslog.d/<new_file>.conf中创建一个包含以下内容的文件:

if $programname == '<your program identifier>' then /path/to/log/file.log
& stop

之后,将该路径的权限更改为syslog可读的内容。

# ls -alth /var/log/syslog 
-rw-r----- 1 syslog adm 439K Mar  5 19:35 /var/log/syslog
# chown syslog:adm /path/to/log/file.log

重新启动rsyslog(sudo systemctl restart rsyslog)并享受!你的程序stdout / stderr仍然可以通过journalctl(sudo journalctl -u <your program identifier>)获得,但它们也可以在你选择的文件中找到。

来源:http://wiki.rsyslog.com/index.php/Filtering_by_program_name(已损坏的链接,可在Archive.org上找到存档)

答案 1 :(得分:42)

如果您有较新的发布版class Program { static void Main(string[] args) { var serial = Setup(); // send your command from here //var command = Command.Authentication.GetStringValue(); //serial.WriteLine(command); Console.ReadLine(); } static SerialPort Setup() { SerialPort serialport = new SerialPort("COM5"); serialport.BaudRate = 115200; serialport.Parity = Parity.None; serialport.StopBits = StopBits.One; serialport.DataBits = 8; serialport.Handshake = Handshake.None; serialport.DtrEnable = true; serialport.RtsEnable = true; serialport.ReceivedBytesThreshold = 1; serialport.DataReceived += serialPort_DataReceived; serialport.Open(); return serialport; } private static void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { var s = (SerialPort) sender; int n; var data = new List<byte>(); do { n = s.BytesToRead; var buffer = new byte[n]; try { var size = s.Read(buffer, 0, buffer.Length); data.AddRange(buffer); } catch (Exception ex) { } } while (n > 0); // you should raise your own event passing your data to your ui to exit this method // for demo only var yourdata = Encoding.ASCII.GetString(data.ToArray()); Console.WriteLine(yourdata); } } systemd version 236 or newer,则可以将systemdStandardOutput的值设置为StandardError。< / p>

长篇故事:

在较新版本的file:YOUR_ABSPATH_FILENAME中,有一个相对较新的选项(the github request is from 2016 ish and the enhancement is merged/closed 2017 ish),您可以将systemdStandardOutput的值设置为StandardErrormost recent systemd.exec man page中记录了file:YOUR_ABSPATH_FILENAME选项。

这个新功能相对较新,因此不适用于像centos-7(或之前的任何中心)这样的旧发行版。

答案 2 :(得分:39)

您可能会收到此错误:

compile("org.springframework.boot:spring-boot-starter:1.3.5.RELEASE")
compile("org.springframework.cloud:spring-cloud-starter-aws-messaging:1.1.0.RELEASE")

来自Failed to parse output specifier, ignoring: /var/log1.log 手册页:

  

systemd.exec(5)

     

控制已执行进程的文件描述符1(STDOUT)所连接的位置。采用StandardOutput=inheritnullttyjournalsyslogkmsgjournal+console之一,syslog+consolekmsg+console

socket手册页介绍了与日志记录相关的其他选项。另请参阅systemd.exec(5)systemd.service(5)手册页。

或者也许你可以尝试这样的事情(全部在一条线上):

systemd.unit(5)

答案 3 :(得分:11)

如果由于某种原因无法使用rsyslog,这样做: ExecStart=/bin/bash -ce "exec /usr/local/bin/binary1 agent -config-dir /etc/sample.d/server >> /var/log/agent.log 2>&1"

答案 4 :(得分:6)

我建议在系统stdout文件本身中添加stderrservice文件。

配置后,它应该不会:

StandardOutput=/var/log1.log
StandardError=/var/log2.log

应为:

StandardOutput=file:/var/log1.log
StandardError=file:/var/log2.log

确保已创建目录。我猜它不支持创建目录。

答案 5 :(得分:0)

假设日志已放置到 stdout / stderr ,并且已在/var/log/syslog

中添加了systemd单元的日志
journalctl -u unitxxx.service

Jun 30 13:51:46 host unitxxx[1437]: time="2018-06-30T11:51:46Z" level=info msg="127.0.0.1
Jun 30 15:02:15 host unitxxx[1437]: time="2018-06-30T13:02:15Z" level=info msg="127.0.0.1
Jun 30 15:33:02 host unitxxx[1437]: time="2018-06-30T13:33:02Z" level=info msg="127.0.0.1
Jun 30 15:56:31 host unitxxx[1437]: time="2018-06-30T13:56:31Z" level=info msg="127.0.0.1

配置rsyslog (系统日志记录服务)

# Create directory for log file
mkdir /var/log/unitxxx

# Then add config file /etc/rsyslog.d/unitxxx.conf

if $programname == 'unitxxx' then /var/log/unitxxx/unitxxx.log
& stop

重新启动rsyslog

systemctl restart rsyslog.service

答案 6 :(得分:0)

简短答案:

class Player(models.Model):

    name = models.CharField(max_length = 256, unique=True)
    number = models.IntegerField()
    age = models.IntegerField()
    is_captain = models.BooleanField(default = False)

class Injuries(models.Model):

    player = models.ForeignKey(Player, to_field='name', on_delete=models.CASCADE)
    team = models.ForeignKey(Team)

如果您不想每次运行该服务时都清除文件,请改用append:

StandardOutput=file:/var/log1.log
StandardError=file:/var/log2.log

答案 7 :(得分:-1)

我们正在使用带有systemd的Spring Boot应用程序Centos7。我正在如下运行Java。并将StandardOutput设置为file对我不起作用。

ExecStart=/bin/java -jar xxx.jar  -Xmx512-Xms32M

以下解决方法在未设置StandardOutput的情况下工作。通过sh如下运行java。


ExecStart=/bin/sh -c 'exec /bin/java -jar xxx.jar -Xmx512M -Xms32M >> /data/logs/xxx.log 2>&1'

enter image description here