Logstash 转发器作为 Windows 服务

Logstash-forwarder as Windows Service

我正在努力为 Windows 2008 R2 服务器上的 logstash 转发器创建 Windows 服务。

我的设置如下所示:

Ubuntu 服务器 14.04 LTS

Windows 服务器 2008 R2:

我目前正在使用此处的说明通过为 Windows 编译的 Logstash 转发器成功地将日志发送到 ELK-Stack...https://github.com/elastic/logstash-forwarder。唯一的问题是,我必须 运行 CLI window 中的 logstash 转发器,而且我无法将其设置为 Windows 服务。

我尝试了以下 SC 命令,服务已创建,但根本无法启动。只是返回以下错误:服务没有及时响应启动或控制请求。

sc create LogstashForwarder binpath= "\"C:\_Logstash\logstash-forwarder.exe\" -config=\"C:\_Logstash\logstash-forwarder.conf\"" start= Auto displayname= "Logstash forwarder" 

很遗憾Google也不知道任何答案。

是否有人能够使用 SC 命令在 Windows 上将 logstash 转发器作为 Windows 服务启动?一些好的建议将不胜感激。

如果您的 logstash 配置正确,请尝试这些步骤。

  1. 获取nssm
  2. 在logstash的bin文件夹中解压nssm zip
  3. 从命令行执行 nssm install logstash

  4. 在启动的配置屏幕上添加您的 bat 的路径

  5. 也添加您的启动目录。

在这里您可以获得更多帮助

https://blog.basefarm.com/blog/how-to-install-logstash-on-windows-server-2012-with-kibana-in-iis/

https://github.com/verbosemode/public-notes/blob/master/logstash-windows.md

希望对您有所帮助

为了补充 Rys 的回答,Logstash-Forwarder 本身不会读取 Windows 事件日志。在研究如何解决这个问题时,我遇到了 Sean-M 的 this gist

我修改了他的原始脚本,以便 Powershell 脚本启动 LSF,然后将事件日志通过管道传输到标准输入中。然后我将 NSSM 指向脚本并将 运行 作为一项服务。如果您的配置文件设置如下:

        {
          "network": {
            "servers": [ "<logstash IP>:5000" ],
            "timeout": 15,
            "ssl ca": "C:/path/to/logstash-forwarder.crt"
          },
          "files": [
                {
                  "paths": [
                     "C:/inetpub/logs/LogFiles/W3SVC*/*.log"
                   ],
                   "fields": { "type": "iis-w3svc" }
                },
                {
                  "paths": [
                    "-"
                  ],
                  "fields": { "type": "windows-event" }
                }
          ]
        }

LSF 将捕获 JSON 输入并将其发送到 Logstash。下面的 Powershell 代码**:

#Requires -Version 3
param (
    [string]$lognames
)

#reading security log requires elevated privileges so only read Application and System for now
[string[]]$logname = $("Application", "System" )

if ($lognames)
{
    [string[]]$logname = $lognames -split ", "
}


##################################
#            Functions           #
##################################

function EvenSpace{
    param ($word) 

    $tabWidth = 48

    $wordTabs = $tabWidth - $word.Length
    $tabNum = [Math]::Floor($($wordTabs/4)) / 2

    ("`t" * $tabNum)
}


## Read events, write to file
function ReadEvents {
    param ([hashtable]$filter, [string]$OutFile=[String]::Empty)

    ## Make it look pretty if writting to stdout    
    try {
        [object[]]$data = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | sort RecordId

        [int]$count = 0
        if ((-not $data -eq $null) -or ($data.Count -gt 0)) {            
            $count = $data.Count
        }


        Write-Verbose ("Log: $($filter["LogName"])" + (EvenSpace -word $filter["LogName"]) + "Count: $count")
    }
    catch {
        $Error[0]
        Write-Verbose ""
        Write-Verbose "Filter:"
        $filter
        return
    }


    if ($data.Count -gt 0) {

        foreach ($event in $data) {
            $json = $event | ConvertTo-Json -Compress
            #$jsonbytes = @($json)
            #$process.StandardInput.BaseStream.Write($jsonbytes,0,$jsonbytes.Count)

            Write-Verbose $json

            $process.StandardInput.WriteLine($json)
        }
    }
}

## Use a try/catch/finally to allow for the inputs to be closed and the process stopped
[System.Diagnostics.Process]$process = $null
$endTime = Get-Date

try
{
    ## Prepare to invoke the process
    $processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
    $processStartInfo.FileName = (Get-Command .\logstash-forwarder.exe).Definition
    $processStartInfo.WorkingDirectory = (Get-Location).Path
    $processStartInfo.Arguments = "-config logstash-forwarder.conf"
    $processStartInfo.UseShellExecute = $false

    ## Always redirect the input and output of the process.
    ## Sometimes we will capture it as binary, other times we will
    ## just treat it as strings.
    $processStartInfo.RedirectStandardOutput = $true
    $processStartInfo.RedirectStandardInput = $true

    $process = [System.Diagnostics.Process]::Start($processStartInfo)

    ##################################
    #           Main Logic           #
    ##################################

    ## Loop to capture events
    while ($true) {
        [String]::Empty | Write-Verbose

        Start-Sleep -Seconds 5

        $startTime = $endTime

        [TimeSpan]$diff = (Get-Date) - $startTime
        if ($diff.TotalHours -gt 1) {
            $endTime = $startTime + (New-TimeSpan -Minutes 30)
        }
        else {
            $endTime = Get-Date
        }

        Write-Verbose "Starting timespan $($startTime) -> $($endTime)"

        ## Supports reading multiple logs
        if ($logname.Count -gt 1) {
            foreach ($log in $logname) {
                ReadEvents -filter @{LogName=$log; StartTime=$startTime; EndTime=$endTime} -OutFile $output
            }
        }
        else {
            ReadEvents -filter @{LogName=$logname; StartTime=$startTime; EndTime=$endTime} -OutFile $output
        }
    }
}
catch
{
    Write-Error $error[0]|format-list -force
    throw $_.Exception
}
finally
{
    if($process)
    {
        $process.StandardInput.Close()
        $process.Close()
    }
}

** 该脚本并没有真正处理 LSF 失败,但它现在可以满足我的目的。

尝试使用 nssm 在答案下添加它。您还可以使用以下命令从没有 UI.

的命令行创建服务

只需确保 nssm.exe 与您 运行 脚本在同一目录中(或者只是编辑脚本)。

@echo off
set BASE_DIR=C:\temp\logstash-forwarder
nssm install Logstash-Forwarder "%BASE_DIR%\logstash-forwarder.exe"
nssm set Logstash-Forwarder AppDirectory "%BASE_DIR%"
nssm set Logstash-Forwarder AppStopMethodSkip "6"
nssm set Logstash-Forwarder AppParameters "-config %BASE_DIR%\logstash-forwarder.conf"