본문 바로가기

.NET/C#

Powershell로 Http 모니터링하기

출처: https://www.codeproject.com/Articles/1214947/Http-Monitor-using-Powershell


소개

이것은 MSSQL 데이터베이스에 로그인하는 일련의 http 호스트를 모니터링하는 Powershell 도구입니다. 여기 에서 최신 버전을 다운로드하고 공식 git-hub를  확인할 수 있습니다 . Powershell 기본 사항을 이해하고 PowerShell 기능에 대한 좋은 예를 신속하고 더러운 응용 프로그램을 만드는 좋은 사례입니다. 또한, 이것은 통증이나 외부 서비스없이 실제 웹 사이트를 모니터링하는 훌륭한 도구입니다.

 

Http 리소스를 모니터링하는 Powershell 도구가 필요한 이유

이 도구는 외부 서비스를 사용하거나 복잡한 소프트웨어를 설치하지 않고 웹 사이트를 모니터링하기위한 스위스 나이프로 필요합니다. 일부 사이트를 모니터링해야 할 수도 있습니다. 또한 디버깅을 테스트하고 거대한 도구를 채택하는 데 너무 많은 시간을 소비하고 싶지 않을 수도 있습니다. 또는 복잡한 통계를 수집하거나 비즈니스 로그인을 모니터에 추가하도록 사용자 정의 할 수있는 모니터 도구가 필요할 수 있습니다.

이 프로젝트는 가능한 한 간단하게 유지하려고 노력하기 때문에 간단한 powershell 스크립트 일뿐입니다.  , 하나의 파일  다운로드하여 실행하면됩니다. 설치 프로세스, 프레임 워크 또는 필수 구성 요소 다운로드에 대해 걱정할 필요가 없습니다. 그냥 다운로드하여 실행하십시오. 알았어? 그러면 powershell이 ​​Windows 서비스로 설치됩니다. 모든 설정은 스크립트로 직접 조정하거나 외부 설정 파일을 사용하여 조정할 수 있습니다. 서비스가 실행되면 정기적으로 웹 사이트 목록을 다시로드하고 각 항목을 호출하여 결과를 데이터베이스에 저장합니다.

모니터링

모니터링은 큰 주제이며 웹 사이트 모니터링에 중점을두고 싶습니다.이 내용은이 기사의 동작과 관련이 있습니다. 웹 사이트를 가진 사람은 누구나 상황이 잘못 될 수 있음을 알고 있습니다. 왜? 모든 웹 devolper는 간단한 웹 사이트가 제공되는 정적 리소스 이상의 것을 알고 있습니다. 요청을 정교하게 만드는 웹 서버, "엔진"(PHP, ASP.NET, Java ...)과 가장 간단한 경우의 데이터베이스가 있습니다 ... 요즘이 구성은 실제로 가장 간단한 것입니다. 가끔 뭔가가 코드에서, 웹 서버 서버, 네트워크, OS에서 잘못 될 수 있습니다 ... 모니터 시스템이 우리를 도울 수있는 방법은 무엇입니까? 물론 모니터링을 통해 실제 문제를 해결하는 것은 아니지만 문제를 예방하고 신속하게 해결하는 데 도움이 될 수 있습니다. 당신은 단순한 웹 사이트를 위해 많은 것을 생각합니까? 확실합니까? 우리의 웹 사이트는 고객이 그것을 통해 우리에게 도달 할 수있는 한 우리 사업의 일부입니다. 귀하의 웹 사이트가 99 %의 시간에도 불구하고, 이것은 고객이 한 달에 약 7 시간 이내에 귀하에게 연락 할 수 없음을 의미합니다. 그게 좋지 않을거야.

이 기사의 초점은 웹 사이트가 언제 위나 아래인지를 구별하는 데 도움이되는 능동적 인 모니터링을 만드는 것에 관한 것입니다. 이 도구는 요청을 실행하고 결과를 해석하여 표준 http (s) 서비스를 모니터링합니다. 응답이 올바르지 않으면 (즉, 응답 본문이 비어 있지 않은 HTTP 상태 200) 경고 메시지가 표시되며, 어쨌든 로그가 데이터베이스에 기록됩니다. 따라서 통계를 얻거나 웹 사이트 약점을 감지 할 수 있습니다. 시스템이 인공 트래픽을 대상에 주입하고 결과를 확인하기 때문에 이를  능동 모니터링 이라고합니다 ( 수동 모니터링 대신  실제 트래픽의 결과를 분석하는 일부 프로브가있는 경우) ...).

Powershell에서 Http-Monitor 구현하기

이 장에서는 가장 중요한 부분을 알아 보겠습니다. 이렇게하면 "비표준"부분에 초점을 맞추고 싶습니다. 왜냐하면 더 흥미로운 부분이라고 생각하기 때문입니다. http-monitor가하는 일을 설명하기 시작합니다.

 

  • 설정 파일에서 url리스트 읽기 => 입력 프로세스

  • DNS pints 위치 확인 => 위양성 방지

  • HTTP 호출 만들기, 결과 받기 => Do Check

  • db = 결과 결과 저장

  • 오류 => 경고 발생시 이메일 보내기

 

 

입력 프로세스

이것은 단순히 txt 파일 입력에서 "Get-Content"로 구현됩니다. 각 줄은 모니터링 할 URL을 나타냅니다. 다음은이를 구현하는 스 니펫입니다. 더 많은 설명이 필요하지 않다고 생각합니다.

 

$webSitesToMonitor = Get-Content $dbpath

오 탐지 방지

사이트 또는 URL의 큰 목록을 모니터링해야 할 때이를 유지 관리하는 데 큰 문제가 있습니다. 진짜 문제는 웹 사이트가 해고되거나 다른 서버 또는 서비스 공급 업체로 이전 될 수 있다는 것입니다. 그래서, 나는 http-monitor에 어떤 서버 IP가 고려해야 하는지를 알릴 수있는 가능성을 소개했다. 조건은 다음과 같습니다.

  1. 나는 많은 서버, 즉 서버 A, 서버 B

  2. 처음에는이 2 개의 서버에 1000 개의 사이트가있었습니다.

  3. 자, 일부 웹 사이트가 서비스 공급 업체를 변경했으며 더 이상 책임지지 않습니다.

 

확실한 해결책은 더 이상 유용한 항목을 제거하는 입력 목록을 변경하는 것입니다, 나는 당신과 동의합니다. 실제 단어에서는 서버에 호스팅 된 웹 사이트 만 모니터링해야한다는 사실을 시스템에 알리면 유용하지 않은 사항을 모니터링하지 않고 비 관련 경고를 관리하지 않아도됩니다. 물론 모니터링이 무시되는 항목을 주기적으로 확인한 다음 결과 목록을 업데이트 할 수 있습니다.

이 시스템은 DNS 확인으로 구현됩니다. DNS가 IP 집합을 가리 키지 않으면 모니터링되지 않습니다.

 

try
{
    $ip=[System.Net.Dns]::GetHostAddresses($line.Substring($line.IndexOf("//")+2))
                          .IPAddressToString
    Write-Host $line " respond to ip " $ip
    $monitorStatus="OK"

    if($monitoring.Length -gt 0)
    {
        $toMonitor=$toMonitor -and $monitoring.Contains($ip)
        if($toMonitor -eq $false)
        {
            $monitorStatus="SKIPPED"
        }
    }
}
catch
{
    $toMonitor=$false
    Write-Warning " $line unable to resolve IP "
    throw $_
    $monitorStatus="NOT RESOLVED"
}

확인

Powershell은 우리에게 간단한 명령을 제공하기 때문에 점검이 더 쉬운 부분입니다. 이렇게하면 상태, 타이밍 등에 대한 정보를 읽을 수있는 요청 객체가 반환됩니다.

 

try
{
    $RequestTime = Get-Date
    $R = Invoke-WebRequest -URI $line -UserAgent $userAgent
    $TimeTaken = ((Get-Date) - $RequestTime).TotalMilliseconds
    $status=$R.StatusCode
    $len=$R.RawContentLength

}
catch
{
    #many http status fall in exception
    $status=$_.Exception.Response.StatusCode.Value__
    $len=0
}

결과 로깅

결과를 저장하는 가장 좋은 방법은 데이터베이스를 사용하는 것입니다. 또한 데이터베이스 의존성을 피하기 위해 CSV 파일에 대해 생각했지만 CSV에서 데이터를 처리하기가 어렵습니다. 복잡한 쿼리를 작성해야 할 때마다 데이터베이스로 가져와야합니다. 그래서 데이터베이스 (MSSQL, 익스프레스 버전은 괜찮습니다!)를 사용하거나이 기능을 사용하지 않기로 결정했습니다. 데이터베이스 작성은 매우 쉽고 일반 ADO.Net을 사용하는 것이 일반적인 관행이었던 2000 년 초에 나를 데려왔다.

 

    # Function used to create table if not exists during setup
    
    
Function CreateTableIfNotExists 
{
[CmdletBinding()]
    Param(
    [System.Data.SqlClient.SqlConnection]$OpenSQLConnection
    )
  $script=@" 
  if not exists (select * from sysobjects where name='logs' and xtype='U')
	CREATE TABLE [logs]
	(	[date] [datetime] NOT NULL DEFAULT (getdate()) ,
		[site] [varchar](500) NULL,
		[status] [varchar](50) NULL,
		[length] [bigint] NULL,
		[time] [bigint] NULL,
        [ip] [varchar](50) NULL,
        [monitored] [varchar](50) NULL
	) ON [PRIMARY]
"@
 $sqlCommand = New-Object System.Data.SqlClient.SqlCommand
    $sqlCommand.Connection = $sqlConnection
 
    # This SQL query will insert 1 row based on the parameters, 
    # and then will return the ID
    # field of the row that was inserted.
    $sqlCommand.CommandText =$script
    $result= $sqlCommand.ExecuteNonQuery()
    Write-Warning "Table log created $result"
}

#-----------------------------------------------------------------------------#
#                                                                             #
#   Function        WriteLogToDB                                              #
#                                                                             #
#   Description     Write a log row to db                                     #
#                                                                             #
#   Arguments       See the Param() block                                     #
#                                                                             #
#   Notes                                                                     #
#                                                                             #
#                                                                             #
#-----------------------------------------------------------------------------#
Function WriteLogToDB { 
    [CmdletBinding()]
    Param(
    [System.Data.SqlClient.SqlConnection]$OpenSQLConnection, 
    [string]$site,
    [int]$status,
    [int]$length,
    [int]$time,
    [string]$ip,
    [string]$monitored
    ) 
 
    $sqlCommand = New-Object System.Data.SqlClient.SqlCommand
    $sqlCommand.Connection = $sqlConnection
 
    # This SQL query will insert 1 row based on the parameters, and then will return the ID
    # field of the row that was inserted.
    $sqlCommand.CommandText =
        "INSERT INTO [dbo].[logs] ([site] ,[status] ,[length] ,[time],[ip],[monitored]) "+
        " VALUES   (@site,@status  ,@lenght ,@time,@ip,@monitored) " 
    $sqlCommand.Parameters.Add(New-Object SqlParameter("@site",[Data.SQLDBType]::NVarChar, 500)) | Out-Null
    $sqlCommand.Parameters.Add(New-Object SqlParameter("@status",[Data.SQLDBType]::NVarChar, 500)) | Out-Null
    $sqlCommand.Parameters.Add(New-Object SqlParameter("@lenght",[Data.SQLDBType]::BigInt)) | Out-Null
    $sqlCommand.Parameters.Add(New-Object SqlParameter("@time",[Data.SQLDBType]::BigInt)) | Out-Null
    $sqlCommand.Parameters.Add(New-Object SqlParameter("@ip",[Data.SQLDBType]::NVarChar, 500))) | Out-Null
    $sqlCommand.Parameters.Add(New-Object SqlParameter("@monitored",[Data.SQLDBType]::NVarChar, 500)) | Out-Null
   
        # Here we set the values of the pre-existing parameters based on the $file iterator
        $sqlCommand.Parameters[0].Value = $site
        $sqlCommand.Parameters[1].Value = $status
        $sqlCommand.Parameters[2].Value = $length
        $sqlCommand.Parameters[3].Value = $time
        $sqlCommand.Parameters[4].Value = $ip
        $sqlCommand.Parameters[5].Value = $monitored
 
        # Run the query and get the scope ID back into $InsertedID
        $InsertedID = $sqlCommand.ExecuteScalar()
        # Write to the console.
        # "Inserted row ID $InsertedID for file " + $file.Name
    
 
}
    
    # Funtion that write a single line of log
    
    
    #... and its usage into monitor cycle
    
    #if db write is enabled log into SQL SERVER
    if($writeToDB -eq $true)
    {
        WriteLogToDB $sqlConnection $line $status $len $TimeTaken $ip $monitored
    }

경고

내가 촬영 한 간단한 경고 시스템은 전자 메일 경고였습니다. 나는 요즘 우리가 우편으로 비 관련 정보의 수천에 의해 채굴된다는 것을 알고 있으므로 냄비에서 찾기가 어려울 수 있습니다. 어쨌든, UI가없는 세계에서 가장 간단한 도구로 설계된이 도구는 여전히 최상의 선택입니다. 또한 이벤트 로그 작성기를 작성하거나 syslog 또는 유사한 시스템을 사용하여 로그를 보내려했습니다. 문제는이 시나리오에서 우리는 이러한 시스템으로부터 오류로 "물리적으로"통보되도록 수동으로 알림을 설정한다는 것입니다.


PowerShell은 다음과 같은 기능을 제공하므로 구현이 매우 쉽습니다.

#if send mail is enabled send an alert
if($sendEmail -eq $true -and $emailErrorCodes.Length -ge 0 -and $emailErrorCodes.Contains( $R.StatusCode) )
{
$statusEmail=$R.StatusCode
$content=$R.RawContent



    $subject="$errorSubject $line"
    $body= @".. this value is omitted for readability "@
    #prepare attachment
    $attachment="$workingPath\tmp.txt"
    # In case some previous execution goes in error whitout deleting the temp file
    Remove-Item $workingPath\tmp.txt -Force
    Write-Host $attachment
    $content|Set-Content $attachment

    #send email
    Write-Host "Sending  mail notification"
    Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject  -Body $body -Attachments $attachment -Priority High -dno onSuccess, onFailure -SmtpServer $smtpServer

    #remove attachment
    Remove-Item $workingPath\tmp.txt -Force

}

 

지속적인 모니터링

이것은 가장 까다로운 부분입니다. 가장 간단한 해결책은 Windows에서이 powershell을 작업으로 예약하는 것입니다. config로 재생하면이 작업을 x 분마다 수행해야하며 인스턴스가 동시에 시작되지 않아야합니다. 나는 또한 그것을 서비스로 구현했다. 이것은 powleshell을 작업으로 실행했기 때문에 poweshell API를 사용하여 쉽게 자동화 할 수있는 작업 솔루션이기 때문에 실제 필요 이상의 운동이었습니다.

PowerShell을 서비스로 설정하는 방법

나는 우리가 알고있는 모든 실행 파일이 서비스가 될 수 있습니다. 모든 스크립트를 서비스로 실행할 수있는 Linux와 달리 Windows에서는 주어진 구조로 실행 파일을 구현해야합니다. 예를 들어 .net 프레임 워크를 사용하면 ServiceBase 기반 클래스를 구현하여 Start \ Stop 기능을 노출해야합니다. 서비스를 제어하기 위해 OS에서 Start \ Stop API가 필요하기 때문에 다른 모든 언어에서도 마찬가지입니다. PowerShell에서이를 수행하기 위해 다음과 같은 흥미로운 참조 구현을 발견했습니다.

  1. PowerShell 안에 C # 클래스를 문자열로 포함

  2. 이 클래스에서는 PowerShell 스크립트를 호출하는 Start \ Stop 메서드를 구현합니다.

  3. 스크립트의 대부분은 동적이므로 경로와 같은 세부 정보는 설정 중에 설정됩니다.

  4. 설치 방법

    1. 클래스는 실행 매개 변수로 실현됩니다.

    2. 클래스가 컴파일됩니다.

    3. 서비스 호환 가능 실행 파일이 생성됩니다 (스크립트의 동일한 폴더에 있음)

    4. 이 실행 파일은 서비스로 등록됩니다.

 

    # The class script embedded into code (some part are omitter for readability)
    $source = @"
  using System;
  using System.ServiceProcess;
  using System.Diagnostics;
  using System.Runtime.InteropServices;                                 // SET STATUS
  using System.ComponentModel;                                          // SET STATUS
 
 
  public class Service_$serviceName : ServiceBase { 
    [DllImport("advapi32.dll", SetLastError=true)]                      // SET STATUS
    private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
    protected override void OnStart(string [] args) {
      EventLog.WriteEntry(ServiceName, "$exeName OnStart() // Entry. Starting script '$scriptCopyCname' -Start"); // EVENT LOG
      // Set the service state to Start Pending.                        // SET STATUS [
      // Only useful if the startup time is long. Not really necessary here for a 2s startup time.
      serviceStatus.dwServiceType = ServiceType.SERVICE_WIN32_OWN_PROCESS;
      serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
      serviceStatus.dwWin32ExitCode = 0;
      serviceStatus.dwWaitHint = 2000; // It takes about 2 seconds to start PowerShell
      SetServiceStatus(ServiceHandle, ref serviceStatus);               // SET STATUS ]
      // Start a child process with another copy of this script
      try {
        Process p = new Process();
        // Redirect the output stream of the child process.
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.FileName = "PowerShell.exe";
        p.StartInfo.Arguments = "-ExecutionPolicy Bypass -c & '$scriptCopyCname' -Start"; // Works if path has spaces, but not if it contains ' quotes.
        p.Start();
        // Read the output stream first and then wait. (To avoid deadlocks says Microsoft!)
        string output = p.StandardOutput.ReadToEnd();
        // Wait for the completion of the script startup code, that launches the -Service instance
        p.WaitForExit();
        if (p.ExitCode != 0) throw new Win32Exception((int)(Win32Error.ERROR_APP_INIT_FAILURE));
        // Success. Set the service state to Running.                   // SET STATUS
        serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;    // SET STATUS
      } catch (Exception e) {
        EventLog.WriteEntry(ServiceName, "$exeName OnStart() // Failed to start $scriptCopyCname. " + e.Message, EventLogEntryType.Error); // EVENT LOG
        // Change the service state back to Stopped.                    // SET STATUS [
        serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED;
        Win32Exception w32ex = e as Win32Exception; // Try getting the WIN32 error code
        if (w32ex == null) { // Not a Win32 exception, but maybe the inner one is...
          w32ex = e.InnerException as Win32Exception;
        }    
        if (w32ex != null) {    // Report the actual WIN32 error
          serviceStatus.dwWin32ExitCode = w32ex.NativeErrorCode;
        } else {                // Make up a reasonable reason
          serviceStatus.dwWin32ExitCode = (int)(Win32Error.ERROR_APP_INIT_FAILURE);
        }                                                               // SET STATUS ]
      } finally {
        serviceStatus.dwWaitHint = 0;                                   // SET STATUS
        SetServiceStatus(ServiceHandle, ref serviceStatus);             // SET STATUS
        EventLog.WriteEntry(ServiceName, "$exeName OnStart() // Exit"); // EVENT LOG
      }
    }
    protected override void OnStop() {
      EventLog.WriteEntry(ServiceName, "$exeName OnStop() // Entry");   // EVENT LOG
      // Start a child process with another copy of ourselves
      Process p = new Process();
      // Redirect the output stream of the child process.
      p.StartInfo.UseShellExecute = false;
      p.StartInfo.RedirectStandardOutput = true;
      p.StartInfo.FileName = "PowerShell.exe";
      p.StartInfo.Arguments = "-c & '$scriptCopyCname' -Stop"; // Works if path has spaces, but not if it contains ' quotes.
      p.Start();
      // Read the output stream first and then wait.
      string output = p.StandardOutput.ReadToEnd();
      // Wait for the PowerShell script to be fully stopped.
      p.WaitForExit();
      // Change the service state back to Stopped.                      // SET STATUS
      serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED;      // SET STATUS
      SetServiceStatus(ServiceHandle, ref serviceStatus);               // SET STATUS
      EventLog.WriteEntry(ServiceName, "$exeName OnStop() // Exit");    // EVENT LOG
    }
    public static void Main() {
      System.ServiceProcess.ServiceBase.Run(new Service_$serviceName());
    }
  }
"@



# The setup part
try {
    $pss = Get-Service $serviceName -ea stop # Will error-out if not installed
    #service installed. Nothing to do
    Write-Warning "Service installed nothing to do."
    exit 0
  } catch {
    # This is the normal case here. Do not throw or write any error!
    Write-Debug "Installation is necessary" # Also avoids a ScriptAnalyzer warning
    # And continue with the installation.
  }
  if (!(Test-Path $installDir)) {
    New-Item -ItemType directory -Path $installDir | Out-Null
  }
  
  # Generate the service .EXE from the C# source embedded in this script
  try {
    Write-Verbose "Compiling $exeFullName"
    Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly $exeFullName -OutputType ConsoleApplication -ReferencedAssemblies "System.ServiceProcess" -Debug:$false
  } catch {
    $msg = $_.Exception.Message
    Write-error "Failed to create the $exeFullName service stub. $msg"
    exit 1
  }
  # Register the service
  Write-Verbose "Registering service $serviceName"
  $pss = New-Service $serviceName $exeFullName -DisplayName $serviceDisplayName -Description $ServiceDescription -StartupType Automatic

 

참고 : 이 코드는 JFLarvoire scpript (실제적인 훌륭한 작업) 에서 파생되었으며 http-monitor 필요에 맞게 조정되었습니다. PowerShell 스크립트를 Windows 서비스로 실행하는 데 흥미가 있다면 원래 구현을 참조하십시오.

동적 구성

이 점은 많은 서버 또는 모니터링 워크 스테이션을 통해 스크립트를 전달하는 데 중요합니다. 당신이 생각할 수있는 더 쉬운 방법은 스크립트의 맨 위에 상수를 많이 넣은 다음 초기 설정 중에 그것을 변경하는 것입니다. 파일을 덮어 쓰지 않고 파일을 병합 할 수 있도록 파일을 변경했기 때문에 이것은 매우 쉽게 구현할 수 있지만 소프트웨어 변경에 따라 관리하기가 어렵습니다. 그래서 나는 powershell 데이터 파일 솔루션 (psd1 파일)을 가리킨다. 이것은 정적 인 데이터를 제외하고는 외부의 모든 구성 데이터를 저장하는 훌륭한 솔루션입니다. 위의  에서 보셨 듯이 PSD1 파일로 설정을 저장 한 다음 응용 프로그램에로드 할 수 있습니다. 하지만 제 경우에는 많은 매개 변수가 동적입니다. 가장 중요한 문제는 경로에 관한 것입니다. 기본 경로를 정의한 다음 기본 경로와 상대 경로를 연결하여 계산 한 많은 경로를 정의하려고합니다. 또한 데이터베이스의 username \ password를 한 번 정의한 다음 연결 문자열을 동적으로 작성하여 연결 문자열 자체에 매개 변수를 추가 할 수 있습니다.


따라서 이러한 유연성을 얻으려면보다 단순한 솔루션을 사용하기로 결정한다면 아마도 예술적이지만 매우 기능적 일 수 있습니다. 기본 스크립트는 스크립트의 모든 매개 변수를 정의합니다. 즉, 스크립트 자체에서 편집하여 업그레이드를 어렵게 만들려면 계속 수행 할 수 있습니다. 매개 변수 정의 응용 프로그램이 설정 ps1 스크립트를 확인한 후 발견되면 이것은 메인 스크립트에 포함됩니다. 여기에 정의 된 모든 변수는 스크립트 중 하나를 무시합니다. 스크립트가 "진짜"powershell 스크립트라면 변수 연결을 사용하고 필요한 모든 트릭을 만들 수 있습니다.

 

    # DB SETTINGS
# -----------------------------------   
$writeToDB= $true # enable or disable db logging
$DBServer = "(localdb)\Projects" # MSSQL host, usully .\SQLEXPRESS, .\SQLSERVER 
$DBName = "httpstatus" # name of db.(HAVE TO BE CREATED)
# full connection string. Write here password if not in integrated security
$ConnectionString = "Server=$DBServer;Database=$DBName;Integrated Security=True;" 

# EMAIL SETTINGS
# -----------------------------------

#... 

# MONITOR SETTINGS
# ----------------------------------   

# ...

# LOGGING FILES
# ----------------------------------

#....


if ( (Test-Path -Path $workingPath\settings.ps1))
{
    Write-Host "Apply external changes"
   . ("$workingPath\settings.ps1") 
}

 

설정보기 : 사용법

설치하는 방법

간단히 말해 PowerShell Http Monitor 도구에는 세 가지 용도가 있습니다.

  • 독립 실행 형 응용 프로그램으로 수동 실행

  • 예정된 작업으로 주기적으로 예약됩니다.

  • 백그라운드에서 지속적으로 운영되는 서비스

한 번 실행

이 명령을 실행하면 스크립트가 모든 웹 사이트를 읽고 MSSQL 데이터베이스 또는 로그 파일로 결과를 다운로드합니다. 이 사용 모드에서는 설치가 필요하지 않습니다. 또한 Windows 예약 된 작업을 사용하여 예약 할 수도 있습니다.

HTTP - 모니터 - 실행

예약 된 작업으로 실행

PowerShell의 Http 모니터 도구 설정구성이 매우 쉽습니다. 주요 설정 :

  • 5 분마다 (또는 다른 간격으로)

  • 스크립트 경로를 설정하십시오.

  • 여러 인스턴스를 시작하지 않도록 스케줄러에 알리기

모든 단계의 스크린 샷보기 :

  1. 새 예약 된 작업 만들기

  2. 설정 타이밍 :  트릭은 한 번 (지금) 시작하는 작업을 정의하지만 x 분 마다 무기한 반복됩니다 .

  3. 시작 스크립트 정의 :  이것은 쉽습니다. 편집 상자에 텍스트를 입력하면됩니다 (절대 파일 경로로 바꾸십시오). Powershell -file "<pathtofile> \ Http-Monitor.ps1" 

여러 인스턴스 피하기

마법사의 마지막 단계는 동시에 여러 인스턴스를 피하기 위해 필요합니다. 드롭 다운 메뉴에서 "새 인스턴스 허용 안 함"을 선택하십시오.

서비스로 실행

그러면 서비스로 powershell 스크립트가 설치됩니다.

PS> Http-Monitor -Setup

한번 설치되면 스크립트 나 service.mmc를 사용하여 제어 할 수 있습니다.

PS> Http-Monitor -Start

PS> Http-Monitor -Stop

구성

Powershell Http Monitor는 UI가없는 마른 응용 프로그램이므로 구성이 가장 까다로운 부분이지만 결국에는 배울 점이 거의 없습니다.

  1. 응용 프로그램 설정 : 기본 응용 프로그램 스크립트 내에서 또는 외부 스크립트를 사용하여 편집 할 수 있습니다.

  2. 입력 : 각 행에 하나의 호스트가있는 텍스트 파일이 있습니다.

애플리케이션 설정

입력 파일

파일 경로는 응용 프로그램 설정 경로와 일치해야합니다. 파일에는 http 또는 https 접두사가있는 웹 사이트 목록이 있어야합니다. 이것은 보통 홈페이지의 목록이지만, 설계 상 Powershell Monitoring Tool은 다른 URL을 받아 들일 수 있습니다.

IIS에서 웹 사이트 목록 생성

이 기능은 모든 사이트를 하나의 iis 서버로 모니터링하는 데 유용 할 수 있습니다. 이렇게하려면 appcmd 명령을 사용하여 바인딩을 텍스트 파일로 덤프해야합니다. 정규식을 사용하여 사이트 URL 목록으로 쉽게 변환 할 수 있습니다.

설정

다음 두 가지 방법으로 응용 프로그램 설정을 구성 할 수 있습니다.

  1. 편집 스크립트 인라인 ( "응용 프로그램 설정"절 참조)

  2. 설정을 별도의 파일로 관리합니다 (권장). 응용 프로그램은 "settings.ps1"파일을 app 디렉토리로 찾아서 기본 설정을 덮어 씁니다.

남아있는 설정을 복사하여 파일을 올바르게 다운로드 할 수 있습니다.

설정은 매우 이해하기 쉽고주의를 기울이면 올바른 튜닝을 얻을 수 있습니다.

결론

Poweshell은 간단한 솔루션을 매우 신속하게 구축하는 데 도움이되는 강력한 도구입니다. .Net Framework의 모든 것을 잠재적으로 할 수 있다는 사실은 OS와 매우 상호 연결된 내장 함수 세트와 함께 모든 것이 허용되는 곳으로 만듭니다. Powershell은 IDE를 사용하여 OS 레벨 스크립트를 작성하는 데 상당히 혁명적 인 역할을합니다. 이것은 Visual Studio가 아니지만 코드를 작성하고 디버깅하는 데 도움이됩니다. 또한 인터넷에서 공유 할 수있는 리소스와 스크립트의 양은 프로입니다. 그럼 뭐가 문제 야?

PowerShell은 훌륭한 도구라고 말하지만, 여전히 스크립트 도구입니다. 따라서 다른 구조화 된 솔루션으로 중단하고 포기해야하는 시점이 있습니다. 내 opionion 에서이 응용 프로그램은이 한도에 도달합니다. 그것은 db에 쓰고, 입력을 읽고, 이메일 경고를 보내고, 설치합니다. 이 한계까지 Powershell을 밀기는 매우 흥미 롭지 만 앞으로는 다음 단계가 복잡성이 커지면서 다른 플랫폼을 기반으로 할 것이라고 기대할 수 있습니다. ORM없이 db에 쓰기, UI가없는 데이터 읽기, 전자 메일을 고유 한 사용자 경고 미디어로 사용 ... 빠른 결과를 얻고, 우리의 필요와 공유 근처에서 쉽게 녹이기는하지만, 더 이상 필요하지는 않지만 더 이상 없습니다 사용할 수있는 올바른 도구. 

그럼, 다음 단계에 대해서 :이 도구가 다른 사람들에게 유용 할 수 있다면 좋을 것이고 누군가가 그것에 기여한다면 나는 자랑 스러울 것입니다. 이것은 웹 사이트 모니터링을 시작하는 좋은 점이 될 수 있지만 실제 모니터링 도구를 발견 한 흥미로운 경험입니다. 어쩌면 UI가있는 또 다른 스택, 또 다른 기술을 가진 최고의 ...

참고 문헌