Как сделать программу ac #, которая отвечает на события системного журнала в Ubuntu 14.04 и 16.04? - PullRequest
0 голосов
/ 22 февраля 2019

Мое решение реагировать на события системного журнала перестает работать через несколько часов.Я запускал tail -f из C # и подписывался на события DataReceived.Моя проблема в том, что через несколько часов кажется, что он просто перестает работать, не выдавая ошибок и не завершая процесс.Я думаю, что это происходит, когда файл системного журнала переворачивается.

Текущее решение, которое перестает работать через много часов:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using App.Configuration;
using App.LogData;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace IQIngest.SrtWatch.Services
{
    public class SyslogReaderService
    {
        private ILogger<SyslogReaderService> _logger;
        private CancellationTokenSource _cancellationTokenSource;
        private IOptionsSnapshot<AppSettings> _appSettings;
        private ITargetBlock<string> _targetQueue;
        public SyslogReaderService(ILogger<SyslogReaderService> logger,
        CancellationTokenSource cancellationTokenSource,
        IOptionsSnapshot<AppSettings> appSettings,
        ITargetBlock<string> targetQueue)
        {
            _logger = logger;
            _cancellationTokenSource = cancellationTokenSource;
            _appSettings = appSettings;
            _targetQueue = targetQueue;
        }

        public async Task StartReader()
        {
            ProcessStartInfo startInfo = new ProcessStartInfo($"/usr/bin/tail", $"-f {_appSettings.Value.TailedFile}")
            {
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };
            await Task.Factory.StartNew(() =>
            {
                try
                {
                    using (Process tail = new Process()
                    {
                        StartInfo = startInfo
                    })
                    {
                        _cancellationTokenSource.Token.Register(tail.Kill);
                        tail.OutputDataReceived += handleLine;
                        tail.ErrorDataReceived += handleLine;
                        tail.Start();
                        _logger.LogDebug($"Started tail process for file {{@{LogFields.FILENAME_STR}}}.", _appSettings.Value.TailedFile);
                        tail.BeginOutputReadLine();
                        tail.BeginErrorReadLine();
                        tail.WaitForExit();
                        //Stops working and doesn't make it to this line.
                        _logger.LogDebug($"Tail stopped.");
                        if (!_cancellationTokenSource.IsCancellationRequested) _cancellationTokenSource.Cancel();
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"Unhandled exception thrown from {nameof(SyslogReaderService)}.");
                }
            });
        }

        private void handleLine(object sender, DataReceivedEventArgs e)
        {
            _logger.LogDebug($"Posting new line to internal processing queue.");
            _targetQueue.Post(e.Data);
        }
    }
}

Если есть очевидная проблема с моим кодом выше, которая бы исправила эту проблемутогда было бы просто найти простое решение, однако я думаю, что мне, возможно, потребуется другой подход.

Сначала позвольте мне сказать, что мое понимание системного журнала не очень сильное, но, насколько я понимаю, вы можетенастроить системный журнал для пересылки событий на «сервер системного журнала».Поэтому я думаю, что я мог бы настроить системный журнал для отправки событий на порт localhost и чтобы мое приложение реагировало на эти события.С этим решением я думаю, что смогу обойти неопределенность настройки файла, а также справиться с прокруткой файла, если я просто буду постепенно читать и оценивать, какие строки новые.Так что, если нет очевидной проблемы с моим решением, то как мне настроить syslog для отправки копий событий в мое приложение c #, работающее локально?

...