只统计近2小时的扫描情况

This commit is contained in:
陈国伟 2021-06-17 09:36:03 +08:00
parent 988d1d5399
commit b1a4a79d64
7 changed files with 109 additions and 107 deletions

View File

@ -5,6 +5,12 @@ namespace FastGithub.Scanner
{ {
sealed class GithubContext : IEquatable<GithubContext> sealed class GithubContext : IEquatable<GithubContext>
{ {
private record Github(
string Domain,
IPAddress Address,
double SuccessRate,
TimeSpan AvgElapsed);
/// <summary> /// <summary>
/// 获取域名 /// 获取域名
/// </summary> /// </summary>
@ -21,9 +27,9 @@ namespace FastGithub.Scanner
public bool Available { get; set; } public bool Available { get; set; }
/// <summary> /// <summary>
/// 获取统计信息 /// 获取扫描历史信息
/// </summary> /// </summary>
public GithubContextStatistics Statistics { get; } = new(); public GithubContextHistory History { get; } = new();
public GithubContext(string domain, IPAddress address) public GithubContext(string domain, IPAddress address)
@ -46,5 +52,15 @@ namespace FastGithub.Scanner
{ {
return HashCode.Combine(this.Domain, this.Address); return HashCode.Combine(this.Domain, this.Address);
} }
public override string ToString()
{
return new Github(
this.Domain,
this.Address,
this.History.GetSuccessRate(),
this.History.GetAvgElapsed()
).ToString();
}
} }
} }

View File

@ -55,8 +55,8 @@ namespace FastGithub.Scanner
{ {
return this.contextList return this.contextList
.Where(item => item.Available && item.Domain == domain) .Where(item => item.Available && item.Domain == domain)
.OrderByDescending(item => item.Statistics.GetSuccessRate()) .OrderByDescending(item => item.History.GetSuccessRate())
.ThenBy(item => item.Statistics.GetAvgElapsed()) .ThenBy(item => item.History.GetAvgElapsed())
.Select(item => item.Address) .Select(item => item.Address)
.FirstOrDefault(); .FirstOrDefault();
} }

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
namespace FastGithub.Scanner
{
sealed class GithubContextHistory
{
private record ScanLog(DateTime ScanTime, TimeSpan Elapsed);
private readonly Queue<ScanLog> successLogs = new();
private readonly Queue<ScanLog> failureLogs = new();
private static readonly TimeSpan keepLogsTimeSpan = TimeSpan.FromHours(2d);
public void AddSuccess(TimeSpan elapsed)
{
ClearStaleData(this.successLogs, keepLogsTimeSpan);
this.successLogs.Enqueue(new ScanLog(DateTime.Now, elapsed));
}
public void AddFailure()
{
ClearStaleData(this.failureLogs, keepLogsTimeSpan);
this.failureLogs.Enqueue(new ScanLog(DateTime.Now, TimeSpan.Zero));
}
static void ClearStaleData(Queue<ScanLog> logs, TimeSpan timeSpan)
{
var time = DateTime.Now.Subtract(timeSpan);
while (logs.TryPeek(out var log))
{
if (log.ScanTime < time)
{
logs.TryDequeue(out _);
}
break;
}
}
/// <summary>
/// 获取成功率
/// </summary>
/// <returns></returns>
public double GetSuccessRate()
{
var successCount = this.successLogs.Count;
var totalScanCount = successCount + this.failureLogs.Count;
return totalScanCount == 0 ? 0d : (double)successCount / totalScanCount;
}
/// <summary>
/// 获取平均耗时
/// </summary>
/// <returns></returns>
public TimeSpan GetAvgElapsed()
{
var totalScanCount = this.successLogs.Count + this.failureLogs.Count;
if (totalScanCount == 0)
{
return TimeSpan.MaxValue;
}
var totalSuccessElapsed = TimeSpan.Zero;
foreach (var item in this.successLogs)
{
totalSuccessElapsed = totalSuccessElapsed.Add(item.Elapsed);
}
return totalSuccessElapsed / totalScanCount;
}
}
}

View File

@ -1,58 +0,0 @@
using System;
namespace FastGithub.Scanner
{
sealed class GithubContextStatistics
{
/// <summary>
/// 扫描总次数
/// </summary>
public int TotalScanCount { get; private set; }
/// <summary>
/// 扫描总成功次数
/// </summary>
public int TotalSuccessCount { get; private set; }
/// <summary>
/// 扫描总耗时
/// </summary>
public TimeSpan TotalSuccessElapsed { get; private set; }
public void SetScanFailure()
{
this.TotalScanCount += 1;
}
public void SetScanSuccess(TimeSpan elapsed)
{
this.TotalScanCount += 1;
this.TotalSuccessCount += 1;
this.TotalSuccessElapsed = this.TotalSuccessElapsed.Add(elapsed);
}
/// <summary>
/// 获取成功率
/// </summary>
/// <returns></returns>
public double GetSuccessRate()
{
return this.TotalScanCount > 0 ?
(double)this.TotalSuccessCount / this.TotalScanCount
: 0d;
}
/// <summary>
/// 获取平均耗时
/// </summary>
/// <returns></returns>
public TimeSpan GetAvgElapsed()
{
return this.TotalScanCount > 0
? this.TotalSuccessElapsed / this.TotalScanCount
: TimeSpan.MaxValue;
}
}
}

View File

@ -30,14 +30,12 @@ namespace FastGithub.Scanner
; ;
this.fullScanDelegate = new PipelineBuilder<GithubContext>(appService, ctx => Task.CompletedTask) this.fullScanDelegate = new PipelineBuilder<GithubContext>(appService, ctx => Task.CompletedTask)
.Use<ConcurrentMiddleware>() .Use<ConcurrentMiddleware>()
.Use<ScanOkLogMiddleware>()
.Use<StatisticsMiddleware>() .Use<StatisticsMiddleware>()
.Use<PortScanMiddleware>() .Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>() .Use<HttpsScanMiddleware>()
.Build(); .Build();
this.resultScanDelegate = new PipelineBuilder<GithubContext>(appService, ctx => Task.CompletedTask) this.resultScanDelegate = new PipelineBuilder<GithubContext>(appService, ctx => Task.CompletedTask)
.Use<ScanOkLogMiddleware>()
.Use<StatisticsMiddleware>() .Use<StatisticsMiddleware>()
.Use<PortScanMiddleware>() .Use<PortScanMiddleware>()
.Use<HttpsScanMiddleware>() .Use<HttpsScanMiddleware>()

View File

@ -1,39 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Net;
using System.Threading.Tasks;
namespace FastGithub.Scanner.Middlewares
{
[Service(ServiceLifetime.Singleton)]
sealed class ScanOkLogMiddleware : IMiddleware<GithubContext>
{
private readonly ILogger<ScanOkLogMiddleware> logger;
private record ScanOk(string Domain, IPAddress Address, int TotalScanCount, double SuccessRate, TimeSpan AvgElapsed);
public ScanOkLogMiddleware(ILogger<ScanOkLogMiddleware> logger)
{
this.logger = logger;
}
public async Task InvokeAsync(GithubContext context, Func<Task> next)
{
await next();
if (context.Available)
{
var mesage = new ScanOk(
context.Domain,
context.Address,
context.Statistics.TotalScanCount,
context.Statistics.GetSuccessRate(),
context.Statistics.GetAvgElapsed()
);
this.logger.LogInformation(mesage.ToString());
}
}
}
}

View File

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -8,24 +9,34 @@ namespace FastGithub.Scanner.Middlewares
[Service(ServiceLifetime.Singleton)] [Service(ServiceLifetime.Singleton)]
sealed class StatisticsMiddleware : IMiddleware<GithubContext> sealed class StatisticsMiddleware : IMiddleware<GithubContext>
{ {
private readonly ILogger<StatisticsMiddleware> logger;
public StatisticsMiddleware(ILogger<StatisticsMiddleware> logger)
{
this.logger = logger;
}
public async Task InvokeAsync(GithubContext context, Func<Task> next) public async Task InvokeAsync(GithubContext context, Func<Task> next)
{ {
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
stopwatch.Start();
try try
{ {
stopwatch.Start();
await next(); await next();
} }
finally finally
{ {
stopwatch.Stop(); stopwatch.Stop();
if (context.Available) if (context.Available)
{ {
context.Statistics.SetScanSuccess(stopwatch.Elapsed); context.History.AddSuccess(stopwatch.Elapsed);
this.logger.LogInformation(context.ToString());
} }
else else
{ {
context.Statistics.SetScanFailure(); context.History.AddFailure();
} }
} }
} }