从命令行添加 Azure Application Insights 状态监视器
Add Azure Application Insights Status Monitor from command line
我有几个站点托管在 Azure 上的 VM 上,该 VM 是使用云服务 Webroles 部署的。
有没有人看过从代码或命令行安装状态监视器的示例?目标是将 IIS 站点自动添加到 Azure App Insight,而无需登录远程桌面,如上文 link 所示。
我们运行也解决了这个问题并写了一个脚本,应该插入the existing method for installing VS Online App Insights。
if(${env:InstalledStatusMonitor} -eq 1)
{
Write-Host "Status monitor has already been installed on this machine by this script" -ForegroundColor Green
}
Write-Host "Using chocolatey to install the Web Platform Installer ..." -ForegroundColor Green
iex ((new-object net.webclient).downloadstring('https://chocolatey.org/install.ps1'))
cinst webpi -y
Stop-Process -Name WebPlatformInstaller
Write-Host "Using Web Platform Installer to install Status Monitor ..." -ForegroundColor Green
&"$env:ProgramFiles\Microsoft\Web Platform Installer\WebpiCmd.exe" /Install /AcceptEula /Products:ApplicationInsightsStatusMonitor
Write-Host "Adding app pool account to the 'Performance Monitor Users' local group" -ForegroundColor Green
$group = "Performance Monitor Users"
$user = "Network Service"
$computer = $(Get-WmiObject Win32_Computersystem).name
$de = [ADSI]"WinNT://$computer/$group,group"
$de.psbase.Invoke("Add",([ADSI]"WinNT://$user").path)
Write-Host "Waiting 30 seconds for Status Monitor to finish its install ..." -ForegroundColor Green
Start-Sleep -Seconds 30
Write-Host "Stop-Starting services to enable tracing..." -ForegroundColor Green
# For some reason, even though Status Monitor calls "iisreset.exe /restart"
# calling it here leaves IIS and website stopped.
&iisreset.exe /restart
Write-Host "waiting a few seconds..." -ForegroundColor Yellow
Start-Sleep -Seconds 2
Write-Host "starting..." -ForegroundColor Yellow
Start-Service -Name W3SVC
Get-WebApplication | Select ApplicationPool -Unique | %{ Start-WebAppPool $_.applicationPool }
Get-Website | Start-Website
Write-Host "started" -ForegroundColor Yellow
Write-Host "Cleaning up running applications" -ForegroundColor Green
Stop-Process -Name Microsoft.Diagnostics.Agent.StatusMonitor
Write-Host "Setting environment variable to indicate status monitor has been installed" -ForegroundColor Green
[Environment]::SetEnvironmentVariable("InstalledStatusMonitor", "1", "Machine")
Write-Host "Installation complete" -ForegroundColor Green
I wrote a blog post about it here,所以如果我们 运行 遇到问题而我忘记更新这个 post 你应该可以在那里看到更新。
更新 1
感谢 pksorensen 的直接 link,看起来这是 Web 平台安装程序从中下载包的地方。我为此做了更多工作,现在有了一个完全自动化的流程。 I have a sample repository available here with a working project.. This commit should describe what you need to do to your own web project to get Status Monitor working on a Web Role.
There is a post by Sergey Kanzhelev,表示应该也可以对 worker 角色执行此操作。
以下是所需的各个步骤。如果我有机会研究它,我将尝试提供有关非网络角色的更新:
1。 ServiceDefinition.csdef
将以下启动条目添加到您的 Web 部署项目中,它将在创建或部署角色时 运行。
<ServiceDefinition>
<WebRole>
...
<Startup>
<Task commandLine="Role_Start\Bootstrap.bat" executionContext="elevated" taskType="simple">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
</Variable>
</Environment>
</Task>
</Startup>
</WebRole>
</ServiceDefinition>
2。 WebProject/Role_Start/Bootstrap.bat
这是启动任务调用的批处理文件。它必须放在您的网络项目中。将属性设置为始终将文件复制到输出目录。
:: The basis for this script is described here
:: http://blogs.msdn.com/b/visualstudioalm/archive/2014/04/16/new-agent-for-application-insights-available.aspx
:: The scripts can be downloaded directly from
:: http://go.microsoft.com/fwlink/?LinkID=329971
@echo off
:: Do not attempt to install the agent on an emulated environment
if "%EMULATED%"=="true" goto :EndOfScript
:: Set appropriate execution policy on the host machine
set ExecutionPolicyLevel=RemoteSigned
for /F "usebackq" %%i in (`powershell -noprofile -command "Get-ExecutionPolicy"`) do (
set ExecutionPolicy=%%i
if /I "%%i"=="Unrestricted" goto :AllIsWell
if /I "%%i"=="RemoteSigned" goto :AllIsWell
Powershell.exe -NoProfile -Command "Set-ExecutionPolicy RemoteSigned" < NUL >> NUL 2>> NUL
)
:AllIsWell
Powershell.exe -NoProfile -Command "& '%~dp0InstallStatusMonitor.ps1'" < NUL >> NUL 2>> NUL
echo "done" >"%ROLEROOT%\startup.task.done.sem"
:EndOfScript
exit 0
3。 WebProject/Role_Start/InstallStatusMonitor.ps1
与Bootstrap.bat 文件一样,设置属性以将此文件也复制到输出目录。这是 post 之前
脚本的更新版本
# The basis for this script is described here
# http://blogs.msdn.com/b/visualstudioalm/archive/2014/04/16/new-agent-for-application-insights-available.aspx
# The scripts can be downloaded directly from
# http://go.microsoft.com/fwlink/?LinkID=329971
#Constants
$downloadUrl = "https://go.microsoft.com/fwlink/?LinkID=512247&clcid=0x409"
# Variables
$rootDir = Split-Path $MyInvocation.MyCommand.Path
$downloadPath = Join-Path $rootDir "ApplicationInsightsAgent.msi"
# Functions
# Infrastructure functions
function TryV1
{
param
(
[ScriptBlock] $Command = $(throw "The parameter -Command is required."),
[ScriptBlock] $Catch = { throw $_ },
[ScriptBlock] $Finally = { }
)
& {
$local:ErrorActionPreference = "SilentlyContinue"
trap
{
trap
{
& {
trap { throw $_ }
& $Finally
}
throw $_
}
$_ | & { & $Catch }
}
& $Command
}
& {
trap { throw $_ }
& $Finally
}
}
function Retry
{
param (
[ScriptBlock] $RetryCommand
)
for ($attempts=0; $attempts -lt 5; $attempts++)
{
TryV1 {
& $RetryCommand
break
} -Catch {
if($attempts -lt 4)
{
Log-Message "Attempt:$attempts Exception Occured. Sleeping and Retrying..."
Log-Message $_
Log-Message $_.InvocationInfo.PositionMessage
Start-Sleep -Seconds 1
}
else
{
throw $_
}
}
}
}
function Log-Message
{
param(
[string] $message
)
$logString = ("{0}: {1}" -f (Get-Date), $message)
$unifiedStartupInfoLogPath = Join-Path $rootDir "ApmAgentInstall.log"
Add-Content $unifiedStartupInfoLogPath $logString
Write-Host $logString -ForegroundColor Green
}
function Log-Error
{
param(
[string] $message
)
$logString = ("{0}: {1}" -f (Get-Date), $message)
$unifiedStartupErrorLogPath = Join-Path $rootDir "ApmAgentInstallError.log"
Add-Content $unifiedStartupInfoLogPath $logString
Write-Host $logString -ForegroundColor Red
}
# Functions
# Operations functions
function Get-AppInsightsInstallationStatus(){
if(${env:InstalledStatusMonitor} -eq 1)
{
return $true
}
else
{
return $false
}
}
function Download-StatusMonitor
{
Retry {
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($downloadUrl, $downloadPath)
}
}
function Install-StatusMonitor(){
$logPath = Join-Path $rootDir "StatusMonitorInstall.log"
&$downloadPath /quiet /passive /log $logPath
Log-Message "Waiting 30 seconds for Status Monitor to finish its install ..."
Start-Sleep -Seconds 30
}
function Grant-LoggingPermissionToAppPool(){
$groupName = "Performance Monitor Users"
$user = "Network Service"
$group = [ADSI]"WinNT://./$groupName,group"
if(($group.PSBase.Invoke('Members') | %{$_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)}) -contains $user)
{
Log-Message "'$user' is already a member of '$groupName', don't need to do anything"
return
}
else
{
Log-Message "'$user' is now a member of '$groupName'"
$group.Add("WinNT://$user")
}
}
function Restart-IISOnAzureWebRole(){
# For some reason, even though Status Monitor calls "iisreset.exe /restart"
# calling it here leaves IIS and website stopped.
&iisreset.exe /restart
Log-Message "waiting a few seconds..."
Start-Sleep -Seconds 2
Log-Message "starting..."
Start-Service -Name W3SVC
Get-WebApplication | Select ApplicationPool -Unique | %{ Start-WebAppPool $_.applicationPool }
Get-Website | Start-Website
Log-Message "started"
}
# Main body
Log-Message "Starting Status Monitor installation"
Log-Message "Downloading component..."
Download-StatusMonitor
Log-Message "Installing component..."
Install-StatusMonitor
Log-Message "Adding app pool account to the 'Performance Monitor Users' local group"
Grant-LoggingPermissionToAppPool
Log-Message "Stop-Starting services to enable tracing..."
Restart-IISOnAzureWebRole
Log-Message "Completed installation successfully"
更新 2
如果您需要添加自定义属性以进行跟踪的功能,例如能够根据角色名称或角色实例区分依赖项,您需要比文档中描述的更早进入 Application Insights 管道。
假设您希望能够过滤角色名称和角色实例 ID,您将创建一个自定义上下文初始化程序。
using System.Text.RegularExpressions;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace Utilities
{
public class AppInsightsCurrentRoleIdAsTagInitializer : Microsoft.ApplicationInsights.Extensibility.IContextInitializer
{
public void Initialize(TelemetryContext context)
{
context.Properties["Greenfinch - RoleName"] = RoleEnvironment.CurrentRoleInstance.Role.Name;
context.Properties["Greenfinch - RoleInstanceId"] = InstanceId;
}
private string InstanceId
{
get
{
var instanceId = Regex.Match(RoleEnvironment.CurrentRoleInstance.Id, "\d+$", RegexOptions.Compiled).Value;
return string.IsNullOrWhiteSpace(instanceId)
? "unable to get instance id"
: instanceId;
}
}
}
}
但不是将其插入代码中,而是将其添加到 ApplicationInsights.config 文件中:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
...
<ContextInitializers>
...
<Add Type="Utilities.AppInsightsCurrentRoleIdAsTagInitializer, Utilities" />
</ContextInitializers>
...
</ApplicationInsights>
在我的 IAAS 模型中,我参考了这些 scripts 进行设置,在安装和重新启动 IIS 之前,它还使用直接 msi URL 而不是 Web 平台。
我为此使用了 PowerShell DSC 和某种蓝绿色 IIS 重置,因此没有中断,因此服务器可以配置状态监视器作为初始配置的一部分,应用程序代码可以驱动遥测。
Package AppInsights
{
Ensure = "Present"
Path = "E:\dsc\ApplicationInsightsAgent.msi" # copied at some vm location
Name = "Application Insights Status Monitor"
ProductID = "CBF2C62C-9537-4D8E-9754-92E54A0822D4"
}
如果您的 web.config 没有检测密钥,您可以使用下面的方法在您的 DSC post 安装中为您的网站启用。
Import-Module 'C:\Program Files\Microsoft Application Insights\Status Monitor\PowerShell\Microsoft.Diagnostics.Agent.StatusMonitor.PowerShell.dll'
Start-ApplicationInsightsMonitoring -Name 'your web site' -InstrumentationKey '<KeyHere>'
我有几个站点托管在 Azure 上的 VM 上,该 VM 是使用云服务 Webroles 部署的。
有没有人看过从代码或命令行安装状态监视器的示例?目标是将 IIS 站点自动添加到 Azure App Insight,而无需登录远程桌面,如上文 link 所示。
我们运行也解决了这个问题并写了一个脚本,应该插入the existing method for installing VS Online App Insights。
if(${env:InstalledStatusMonitor} -eq 1)
{
Write-Host "Status monitor has already been installed on this machine by this script" -ForegroundColor Green
}
Write-Host "Using chocolatey to install the Web Platform Installer ..." -ForegroundColor Green
iex ((new-object net.webclient).downloadstring('https://chocolatey.org/install.ps1'))
cinst webpi -y
Stop-Process -Name WebPlatformInstaller
Write-Host "Using Web Platform Installer to install Status Monitor ..." -ForegroundColor Green
&"$env:ProgramFiles\Microsoft\Web Platform Installer\WebpiCmd.exe" /Install /AcceptEula /Products:ApplicationInsightsStatusMonitor
Write-Host "Adding app pool account to the 'Performance Monitor Users' local group" -ForegroundColor Green
$group = "Performance Monitor Users"
$user = "Network Service"
$computer = $(Get-WmiObject Win32_Computersystem).name
$de = [ADSI]"WinNT://$computer/$group,group"
$de.psbase.Invoke("Add",([ADSI]"WinNT://$user").path)
Write-Host "Waiting 30 seconds for Status Monitor to finish its install ..." -ForegroundColor Green
Start-Sleep -Seconds 30
Write-Host "Stop-Starting services to enable tracing..." -ForegroundColor Green
# For some reason, even though Status Monitor calls "iisreset.exe /restart"
# calling it here leaves IIS and website stopped.
&iisreset.exe /restart
Write-Host "waiting a few seconds..." -ForegroundColor Yellow
Start-Sleep -Seconds 2
Write-Host "starting..." -ForegroundColor Yellow
Start-Service -Name W3SVC
Get-WebApplication | Select ApplicationPool -Unique | %{ Start-WebAppPool $_.applicationPool }
Get-Website | Start-Website
Write-Host "started" -ForegroundColor Yellow
Write-Host "Cleaning up running applications" -ForegroundColor Green
Stop-Process -Name Microsoft.Diagnostics.Agent.StatusMonitor
Write-Host "Setting environment variable to indicate status monitor has been installed" -ForegroundColor Green
[Environment]::SetEnvironmentVariable("InstalledStatusMonitor", "1", "Machine")
Write-Host "Installation complete" -ForegroundColor Green
I wrote a blog post about it here,所以如果我们 运行 遇到问题而我忘记更新这个 post 你应该可以在那里看到更新。
更新 1
感谢 pksorensen 的直接 link,看起来这是 Web 平台安装程序从中下载包的地方。我为此做了更多工作,现在有了一个完全自动化的流程。 I have a sample repository available here with a working project.. This commit should describe what you need to do to your own web project to get Status Monitor working on a Web Role.
There is a post by Sergey Kanzhelev,表示应该也可以对 worker 角色执行此操作。
以下是所需的各个步骤。如果我有机会研究它,我将尝试提供有关非网络角色的更新:
1。 ServiceDefinition.csdef
将以下启动条目添加到您的 Web 部署项目中,它将在创建或部署角色时 运行。
<ServiceDefinition>
<WebRole>
...
<Startup>
<Task commandLine="Role_Start\Bootstrap.bat" executionContext="elevated" taskType="simple">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
</Variable>
</Environment>
</Task>
</Startup>
</WebRole>
</ServiceDefinition>
2。 WebProject/Role_Start/Bootstrap.bat
这是启动任务调用的批处理文件。它必须放在您的网络项目中。将属性设置为始终将文件复制到输出目录。
:: The basis for this script is described here
:: http://blogs.msdn.com/b/visualstudioalm/archive/2014/04/16/new-agent-for-application-insights-available.aspx
:: The scripts can be downloaded directly from
:: http://go.microsoft.com/fwlink/?LinkID=329971
@echo off
:: Do not attempt to install the agent on an emulated environment
if "%EMULATED%"=="true" goto :EndOfScript
:: Set appropriate execution policy on the host machine
set ExecutionPolicyLevel=RemoteSigned
for /F "usebackq" %%i in (`powershell -noprofile -command "Get-ExecutionPolicy"`) do (
set ExecutionPolicy=%%i
if /I "%%i"=="Unrestricted" goto :AllIsWell
if /I "%%i"=="RemoteSigned" goto :AllIsWell
Powershell.exe -NoProfile -Command "Set-ExecutionPolicy RemoteSigned" < NUL >> NUL 2>> NUL
)
:AllIsWell
Powershell.exe -NoProfile -Command "& '%~dp0InstallStatusMonitor.ps1'" < NUL >> NUL 2>> NUL
echo "done" >"%ROLEROOT%\startup.task.done.sem"
:EndOfScript
exit 0
3。 WebProject/Role_Start/InstallStatusMonitor.ps1
与Bootstrap.bat 文件一样,设置属性以将此文件也复制到输出目录。这是 post 之前
脚本的更新版本# The basis for this script is described here
# http://blogs.msdn.com/b/visualstudioalm/archive/2014/04/16/new-agent-for-application-insights-available.aspx
# The scripts can be downloaded directly from
# http://go.microsoft.com/fwlink/?LinkID=329971
#Constants
$downloadUrl = "https://go.microsoft.com/fwlink/?LinkID=512247&clcid=0x409"
# Variables
$rootDir = Split-Path $MyInvocation.MyCommand.Path
$downloadPath = Join-Path $rootDir "ApplicationInsightsAgent.msi"
# Functions
# Infrastructure functions
function TryV1
{
param
(
[ScriptBlock] $Command = $(throw "The parameter -Command is required."),
[ScriptBlock] $Catch = { throw $_ },
[ScriptBlock] $Finally = { }
)
& {
$local:ErrorActionPreference = "SilentlyContinue"
trap
{
trap
{
& {
trap { throw $_ }
& $Finally
}
throw $_
}
$_ | & { & $Catch }
}
& $Command
}
& {
trap { throw $_ }
& $Finally
}
}
function Retry
{
param (
[ScriptBlock] $RetryCommand
)
for ($attempts=0; $attempts -lt 5; $attempts++)
{
TryV1 {
& $RetryCommand
break
} -Catch {
if($attempts -lt 4)
{
Log-Message "Attempt:$attempts Exception Occured. Sleeping and Retrying..."
Log-Message $_
Log-Message $_.InvocationInfo.PositionMessage
Start-Sleep -Seconds 1
}
else
{
throw $_
}
}
}
}
function Log-Message
{
param(
[string] $message
)
$logString = ("{0}: {1}" -f (Get-Date), $message)
$unifiedStartupInfoLogPath = Join-Path $rootDir "ApmAgentInstall.log"
Add-Content $unifiedStartupInfoLogPath $logString
Write-Host $logString -ForegroundColor Green
}
function Log-Error
{
param(
[string] $message
)
$logString = ("{0}: {1}" -f (Get-Date), $message)
$unifiedStartupErrorLogPath = Join-Path $rootDir "ApmAgentInstallError.log"
Add-Content $unifiedStartupInfoLogPath $logString
Write-Host $logString -ForegroundColor Red
}
# Functions
# Operations functions
function Get-AppInsightsInstallationStatus(){
if(${env:InstalledStatusMonitor} -eq 1)
{
return $true
}
else
{
return $false
}
}
function Download-StatusMonitor
{
Retry {
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($downloadUrl, $downloadPath)
}
}
function Install-StatusMonitor(){
$logPath = Join-Path $rootDir "StatusMonitorInstall.log"
&$downloadPath /quiet /passive /log $logPath
Log-Message "Waiting 30 seconds for Status Monitor to finish its install ..."
Start-Sleep -Seconds 30
}
function Grant-LoggingPermissionToAppPool(){
$groupName = "Performance Monitor Users"
$user = "Network Service"
$group = [ADSI]"WinNT://./$groupName,group"
if(($group.PSBase.Invoke('Members') | %{$_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)}) -contains $user)
{
Log-Message "'$user' is already a member of '$groupName', don't need to do anything"
return
}
else
{
Log-Message "'$user' is now a member of '$groupName'"
$group.Add("WinNT://$user")
}
}
function Restart-IISOnAzureWebRole(){
# For some reason, even though Status Monitor calls "iisreset.exe /restart"
# calling it here leaves IIS and website stopped.
&iisreset.exe /restart
Log-Message "waiting a few seconds..."
Start-Sleep -Seconds 2
Log-Message "starting..."
Start-Service -Name W3SVC
Get-WebApplication | Select ApplicationPool -Unique | %{ Start-WebAppPool $_.applicationPool }
Get-Website | Start-Website
Log-Message "started"
}
# Main body
Log-Message "Starting Status Monitor installation"
Log-Message "Downloading component..."
Download-StatusMonitor
Log-Message "Installing component..."
Install-StatusMonitor
Log-Message "Adding app pool account to the 'Performance Monitor Users' local group"
Grant-LoggingPermissionToAppPool
Log-Message "Stop-Starting services to enable tracing..."
Restart-IISOnAzureWebRole
Log-Message "Completed installation successfully"
更新 2
如果您需要添加自定义属性以进行跟踪的功能,例如能够根据角色名称或角色实例区分依赖项,您需要比文档中描述的更早进入 Application Insights 管道。
假设您希望能够过滤角色名称和角色实例 ID,您将创建一个自定义上下文初始化程序。
using System.Text.RegularExpressions;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace Utilities
{
public class AppInsightsCurrentRoleIdAsTagInitializer : Microsoft.ApplicationInsights.Extensibility.IContextInitializer
{
public void Initialize(TelemetryContext context)
{
context.Properties["Greenfinch - RoleName"] = RoleEnvironment.CurrentRoleInstance.Role.Name;
context.Properties["Greenfinch - RoleInstanceId"] = InstanceId;
}
private string InstanceId
{
get
{
var instanceId = Regex.Match(RoleEnvironment.CurrentRoleInstance.Id, "\d+$", RegexOptions.Compiled).Value;
return string.IsNullOrWhiteSpace(instanceId)
? "unable to get instance id"
: instanceId;
}
}
}
}
但不是将其插入代码中,而是将其添加到 ApplicationInsights.config 文件中:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
...
<ContextInitializers>
...
<Add Type="Utilities.AppInsightsCurrentRoleIdAsTagInitializer, Utilities" />
</ContextInitializers>
...
</ApplicationInsights>
在我的 IAAS 模型中,我参考了这些 scripts 进行设置,在安装和重新启动 IIS 之前,它还使用直接 msi URL 而不是 Web 平台。
我为此使用了 PowerShell DSC 和某种蓝绿色 IIS 重置,因此没有中断,因此服务器可以配置状态监视器作为初始配置的一部分,应用程序代码可以驱动遥测。
Package AppInsights
{
Ensure = "Present"
Path = "E:\dsc\ApplicationInsightsAgent.msi" # copied at some vm location
Name = "Application Insights Status Monitor"
ProductID = "CBF2C62C-9537-4D8E-9754-92E54A0822D4"
}
如果您的 web.config 没有检测密钥,您可以使用下面的方法在您的 DSC post 安装中为您的网站启用。
Import-Module 'C:\Program Files\Microsoft Application Insights\Status Monitor\PowerShell\Microsoft.Diagnostics.Agent.StatusMonitor.PowerShell.dll'
Start-ApplicationInsightsMonitoring -Name 'your web site' -InstrumentationKey '<KeyHere>'