65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ElasticSearch+Grafana 构建强大的 IIS/Apache 监控仪表盘

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2016年5月30日

CPOL

8分钟阅读

viewsIcon

81907

使用 ElasticSearch 和 Grafana 构建强大而美观的仪表盘。近乎实时地监控和分析 IIS/Apache 日志

引言

IIS 或 Apache 本身不提供任何监控仪表盘,无法显示每秒请求数、响应时间、慢速 URL、失败请求等图表。您需要使用外部工具来可视化这些数据。ElasticSearch 和 Grafana 就是这样两个工具,它们可以从 Web 服务器收集日志,然后解析、过滤、排序、分析并从中创建精美的演示文稿。ElasticSearch 是一个分布式 JSON 文档存储,类似于 NoSQL 数据库。您可以使用它将日志存储为 JSON 文档。然后,您可以使用 Grafana 从 ElasticSearch 中提取这些文档并构建精美的演示文稿。两者都是免费且开源的。

使用 ElasticSearch 和 Grafana,我构建了上述仪表盘来监控 IIS 和 Apache 网站。我用它来衡量 Web 服务器性能、识别慢速 URL、查看有多少请求失败、识别过载服务器、404 错误等等。您还可以查询特定指标,例如当平均响应时间超过 5 秒时。使用一些简单的命令行脚本,您可以根据这些查询结果构建警报。这种 ElasticSearch+Grafana 的组合可以为您提供应用程序性能的可视化、趋势分析、容量预测、监控和警报——所有这些都是免费的。

这种 ElasticSearch+Grafana 的组合可以为您提供应用程序性能的可视化、趋势分析,帮助您进行容量预测,近乎实时地监控和警报——所有这些都是免费的。

架构

您需要以下产品来构建这样的仪表盘

  • ElasticSearch:用于将日志存储为 JSON 文档并使其可搜索。免费且开源。
  • Grafana:用于查看 ElasticSearch 中的日志并创建精美的仪表盘。免费且开源。
  • Filebeat - ElasticSearch 生态系统的一部分工具。它将服务器上的日志传输到 ElasticSearch。您需要在每台服务器上安装此软件,并告诉它要传输哪些日志文件。免费且开源。
  • Logstash - ElasticSearch 生态系统的一部分工具。它处理 Filebeat 客户端发送的日志,然后解析并将其存储在 ElasticSearch 中。免费且开源。

架构如下

听起来需要安装很多软件。但是,您可以将 ElasticSearch、Logstash、Grafana 安装在同一台服务器上。Filebeat 将在您要从中传输日志的每台服务器上运行。根据您的 Web 服务器生成日志的多少,您可以通过添加更多 ElasticSearch 节点轻松地进行扩展。这里资源消耗最大的组件是 ElasticSearch。其余组件的资源消耗很少。

自动安装

首先,您需要安装 Java 8。它们支持 Java 7,但 8 提供了更好的性能,据我所知。

安装 Java 后,您可以使用我制作的 Powershell 脚本,在一个 Windows PC/Server 上一次性下载、配置和运行所有必要的软件。它将开始从您的本地 IIS 日志文件夹将日志传输到新安装的 ElasticSearch 节点。要使其正常工作,您需要 IIS 7+ 并且已经运行了一个本地网站。否则,将没有任何内容显示。

您需要Powershell 3.0+ 来实现此目的。

启动 Powershell 命令提示符。导航到您想要下载和安装所有内容的文件夹。然后,运行以下命令

Invoke-WebRequest -Uri http://bit.ly/1pks5SY -OutFile SetupELKG.ps1
powershell -File SetupELKG.ps1

脚本执行以下操作

$elasticsearch="https://download.elastic.co/elasticsearch/...
$logstash="https://download.elastic.co/logstash/logstash/...
$filebeat="https://download.elastic.co/beats/filebeat/...
$grafana="https://grafanarel.s3.amazonaws.com/winbuilds/...
$logstashconf="https://gist.githubusercontent.com/oazabir/...
$logstashtemplate="https://gist.githubusercontent.com/oazabir/...
$filebeatconf="https://gist.githubusercontent.com/oazabir/...
$grafanatemplate="https://gist.githubusercontent.com/oazabir/...

if (-not (Test-Path "Elastic")) { ni Elastic -ItemType "Directory" }
cd Elastic | Out-Null

$path=(pwd).ToString()

function Expand-ZIPFile($file, $destination)
{
    Write-Host "Extracting $file -> $destination ...";
    $shell = new-object -com shell.application
    $zip = $shell.NameSpace($file)
    foreach($item in $zip.items())
    {
        $shell.Namespace($destination).copyhere($item)
    }
}

function DownloadAndUnzip($url, $path, $file) {
    Write-Host "Downloading $url -> $path ...";
    $fullpath = Join-Path $path $file;    
    Invoke-WebRequest -Uri $url -OutFile $fullpath
    Expand-ZIPFile $fullpath $path
}

DownloadAndUnzip $filebeat $path "filebeat.zip"
DownloadAndUnzip $grafana $path "grafana.zip"
DownloadAndUnzip $logstash $path "logstash.zip"
DownloadAndUnzip $elasticsearch $path "elasticsearch.zip"

Write-Host "All Downloaded."

Write-Host "Start ElasticSearch..."
cd elasticsearch*
start cmd "/c .\bin\elasticsearch.bat"
cd ..
sleep 5

Write-Host "Start Logstash..."
cd logstash-*
if (-not (Test-Path "conf")) { ni conf -ItemType "Directory" }
cd conf
Invoke-WebRequest -Uri $logstashconf -OutFile logstash.yml
Invoke-WebRequest -Uri $logstashtemplate -OutFile logstash-template.json
cd ..
start cmd "/c .\bin\logstash.bat -f .\conf\logstash.yml"
cd ..
sleep 5

Write-Host "Start Grafana..."
cd grafana*
start cmd "/c bin\grafana-server.exe"
cd ..
sleep 5

Write-Host "Start Filebeat..."
cd filebeat*
Invoke-WebRequest -Uri $filebeatconf -OutFile filebeat_original.yml

# Get IIS web log folders
$SystemDrive = [system.environment]::getenvironmentvariable("SystemDrive")
$logfolder = resolve-path "$SystemDrive\inetpub\logs\LogFiles\"
$iisLogFolders=@()
gci $logfolder | %{ $iisLogFolders += $_.FullName + "\*" }
if ($iisLogFolders.Length -eq 0) { 
   Write-Host "*** There is no IIS Folder configured. You need an IIS website. ***" 
}

# put them all on filebeat.yml
$filebeatconfig = [IO.File]::ReadAllText((Join-Path (pwd) "filebeat_original.yml"));
$padding = "        - "
$logpaths = [string]::Join([Environment]::NewLine + $padding, $iisLogFolders);
$pos = $filebeatconfig.IndexOf("paths:");

$filebeatconfig = $filebeatconfig.Substring(1, $pos+5) + 
[Environment]::NewLine + $padding + $logpaths + $filebeatconfig.Substring($pos+6);
[IO.File]::WriteAllText((Join-Path (pwd) "filebeat.yml"), $filebeatconfig);

start cmd "/c filebeat.exe"
cd ..
sleep 5

$templatePath = Join-Path (pwd) "GrafanaWebLogTemplate.json"
Invoke-WebRequest $grafanatemplate -OutFile $templatePath

Write-Host "########### README CAREFULLY ##########"
Write-Host "I am about to launch Grafana. This is what you need to do:"
Write-Host "1. Login to grafana using admin/admin"
Write-Host "2. Create a new Data source exactly named 'Elasticsearch Logstash'"
Write-Host "    Name: Elasticsearch Logstash"
Write-Host "    Type: ElasticSearch"
Write-Host "    Url: http://127.0.0.1:9200"
Write-Host "    Pattern: Daily"
Write-Host "    Index name: (It will come automatically when you select pattern)"
Write-Host "    Version: 2.x"
Write-Host "    Click Add"

Write-Host "3. Click on Dashboards. Click Import. Import the file: $templatePath"

Sleep 5
pause 

start "http://127.0.0.1:3000"

Write-Host "All done."

脚本运行完成后,您将在四个命令提示符窗口中看到所有四个应用程序已配置并正在运行。如果您关闭了其中任何一个窗口,该应用程序将停止运行。因此,您需要保持这些命令提示符窗口打开。

手动安装

您可以按照下面的说明单独下载和配置它们。

ElasticSearch

访问 https://elastic.ac.cn/downloads/elasticsearch 并下载最新的二进制文件。

然后,在 Unix 上运行 _bin/elasticsearch_,在 Windows 上运行 _bin\elasticsearch.bat_ 即可启动并运行 ElasticSearch 服务器。

一旦它运行正常并且日志正在被传输,Grafana 正在显示数据,您需要将其配置为 Windows 上的服务或 Unix 上的守护进程

Logstash

访问 https://elastic.ac.cn/downloads/logstash 并下载最新的二进制文件。

下载并解压后,在 logstash 解压文件夹内创建一个 _conf_ 文件夹,使该文件夹与 _bin_ 文件夹处于同一级别。然后在此文件夹内,下载 logtash.yml 文件和 logstash-template.json 文件

然后您需要使用以下命令运行 logstash

.\bin\logstash.bat -f .\conf\logstash.yml

如果没有出现任何警告信息,那么它就在运行并且已经加载了正确的配置。

Filebeat

https://elastic.ac.cn/downloads/beats/filebeat 下载。

解压它。里面有一个 _filebeat.yml_ 文件。删除它。然后下载我的 filebeat.yml

打开文件并添加 IIS 日志文件夹的路径。默认情况下,文件看起来是这样的

filebeat:
  # List of prospectors to fetch data.
  prospectors:
    # Each - is a prospector. Below are the prospector specific configurations
    -
      # Paths that should be crawled and fetched. Glob based paths.
      # To fetch all ".log" files from a specific level of subdirectories
      # /var/log/*/*.log can be used.
      # For each file found under this path, a harvester is started.
      # Make sure not file is defined twice as this can lead to unexpected behaviour.
      paths:
        - /var/log/*.log
        #- c:\programdata\elasticsearch\logs\*

添加路径后,它看起来是这样的

filebeat:
  # List of prospectors to fetch data.
  prospectors:
    # Each - is a prospector. Below are the prospector specific configurations
    -
      # Paths that should be crawled and fetched. Glob based paths.
      # To fetch all ".log" files from a specific level of subdirectories
      # /var/log/*/*.log can be used.
      # For each file found under this path, a harvester is started.
      # Make sure not file is defined twice as this can lead to unexpected behaviour.
      paths:
        - C:\inetpub\logs\LogFiles\W3SVC1\*
        #- /var/log/*.log
        #- c:\programdata\elasticsearch\logs\*

这是棘手的部分。缩进行时,请务必使用空格,而不是制表符。大多数编辑器都会用制表符来缩进行。Filebeat 不能使用制表符。必须使用空格。并且确保每个路径前面都有一个连字符。

只需运行 _filebeat.exe_,它就会完成工作。

当一切正常运行时,将其安装为服务。

Grafana

  • 下载 Grafana,解压并运行 _bin\grafana-server.exe_。
  • 然后打开 http://127.0.0.1:3000/。
  • 使用 admin/admin 登录。
  • 点击 Data Sources (数据源)。
  • 添加一个新数据源,名称必须完全是 Elasticsearch Logstash
  • 选择 **Type** 为 ElasticSearch
  • 将 URL 设置为 http://127.0.0.1:9200。
  • 选择 Pattern (模式) 为 Daily (每日)。
  • 选择 Version (版本) 为 2.x。
  • Index name (索引名称) 将自动显示为 [logstash-]YYYY-MM-DD。保持不变。
  • 点击 **Add** (添加)。
  • 现在下载我制作的仪表盘模板
  • 在 Grafana 中,点击 **Dashboards** (仪表盘),然后导入仪表盘模板。
  • 您已准备就绪!

如果您看不到任何图表,则表示没有 IIS 日志被传输。查看 filebeat、logstash、elasticsearch 控制台窗口是否有任何错误。如果没有错误,则说明日志文件中没有数据。

关注点

ElasticSearch

一旦您有了本地安装运行,您就拥有了一个单节点设置。您可以将 ElasticSearch 部署到任意数量的服务器上。通过非常简单的配置更改,ElasticSearch 将自动检测并运行节点集群。有关配置集群的详细指导,请在此处查找。

当您有了集群时,Kopf 插件对于监控集群节点、进行临时配置更改以及操作集群中存储的数据非常有用。在这里,您可以看到一个三节点集群。

要熟悉 ElasticSearch,需要一点学习曲线。但文档非常有帮助。至少,您需要理解 Index (索引)、Template (模板)、Document (文档) 和 clustering (集群)。

ElasticSearch 有一个内置的仪表盘,名为Kibana。我个人认为它在视觉上不吸引人,而且完全没有访问控制。因此我选择了 Grafana。

Logstash

Logstash 从 filebeat 和其他工具接收各种格式的数据,然后解析、格式化并将其保存在 ElasticSearch 的正确索引中。您可以将 Logstash 视为一个中央服务器,用于处理所有传入的日志和其他数据。使用 Logstash,您可以控制哪些数据将被接受到 ElasticSearch 中。

Logstash 会解析 IIS 日志,并将其转换为 ElasticSearch 文档。如果您查看配置,您会看到它是如何解析的。

input {
  beats {
    port => 5045
    type => 'iis'
  }
}

# First filter
filter {
  #ignore log comments
  if [message] =~ "^#" {
    drop {}
  }

  grok {
    patterns_dir => "./patterns"
    match => [
      "message", "%{TIMESTAMP_ISO8601:timestamp} %{IPORHOST:serverip} 
       %{WORD:verb} %{NOTSPACE:request} %{NOTSPACE:querystring} %{NUMBER:port} 
       %{NOTSPACE:auth} %{IPORHOST:clientip} %{NOTSPACE:agent} %{NOTSPACE:referrer} 
       %{NUMBER:response} %{NUMBER:sub_response} %{NUMBER:sc_status} %{NUMBER:responsetime}",
      "message", "%{TIMESTAMP_ISO8601:timestamp} %{IPORHOST:serverip} 
       %{WORD:verb} %{NOTSPACE:request} %{NOTSPACE:querystring} %{NUMBER:port} 
       %{NOTSPACE:auth} %{IPORHOST:clientip} %{NOTSPACE:agent} %{NUMBER:response} 
       %{NUMBER:sub_response} %{NUMBER:sc_status} %{NUMBER:responsetime}",
      "message", "%{TIMESTAMP_ISO8601:timestamp} %{IPORHOST:serverip} 
       %{WORD:verb} %{NOTSPACE:request} %{NOTSPACE:querystring} %{NUMBER:port} 
       %{NOTSPACE:auth} %{IPORHOST:clientip} %{NOTSPACE:agent} %{NUMBER:response} 
       %{NUMBER:sub_response} %{NUMBER:sc_status}" 
    ]
  }
  date {
    match => [ "timestamp", "yyyy-MM-dd HH:mm:ss" ]
    locale => "en"
  }
}

# Second filter
filter {  
  if "_grokparsefailure" in [tags] {

    } else {
    # on success remove the message field to save space
    mutate {
      remove_field => ["message", "timestamp"]
    }
  } 
}

output {  
  elasticsearch {
    hosts =>  ["127.0.0.1:9200"]
    index => "logstash-%{+YYYY.MM.dd}"
    template => "./conf/logstash-template.json"
    template_name => "logstash"
    document_type => "iis"
    template_overwrite => true
    manage_template => true
  }
}

Input 部分指定了要监听的端口。

Filter 是实际处理发生的地方。它应用正则表达式来处理 IIS 日志行并将其转换为 JSON。您会看到多个正则表达式,它们处理各种 IIS 版本中常见的 W3C 日志格式。

如果您添加/删除日志字段,则需要更新此正则表达式。我配置的三个是 IIS 日志文件的默认 W3C 格式。

我添加了第二个过滤器来删除 message 字段,该字段包含接收到的完整日志行。这有助于节省 ElasticSearch 中的存储空间。如果解析成功,就没有必要保留原始消息。

output 部分定义了 Logstash 将日志发送到哪里。它被配置为连接到本地主机的 ElasticSearch。有一个名为 _logstash-template.json_ 的模板文件,其中包含 IIS 日志的索引模板。

Logstash 有一定的学习曲线。您需要正确配置。配置是 YAML 格式的,所以请确保您对这种格式有一定的了解。您可以使用在线 YAML 验证器在启动 logstash 之前检查配置文件。

grok 命令是传入数据的解析器。您可以使用Grok Debugger 工具测试 grok 命令所需的正则表达式。

还有详细文档,介绍了 Logstash 可以接收数据并通过解析并馈送给 ElasticSearch 的各种方式。Logstash 还可以对多个 Elasticsearch 节点进行负载均衡。

结论

ElasticSearch 是一个非常强大的产品。它是一个多用途的分布式 JSON 文档存储,也是一个强大的搜索引擎。ElasticSearch 最常见的用例是创建可搜索文档、实现自动完成功能,以及聚合日志并进行分析。Grafana 是一个美观的仪表盘工具,它将 ElasticSearch 等作为数据源。将这两者结合起来,您可以构建复杂的监控和报告工具,以全面了解您的应用程序的运行状况以及存在的问题。

历史

  • 2016 年 5 月 30 日:初始版本
© . All rights reserved.