Reorganize source code in preparation to move into aspnet/AspNetCore
Prior to reorganization, this source code was found in 082d505977
This commit is contained in:
commit
cb198d727b
|
|
@ -1,17 +0,0 @@
|
|||
init:
|
||||
- git config --global core.autocrlf true
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^release\/.*$/
|
||||
- /^(.*\/)?ci-.*$/
|
||||
build_script:
|
||||
- ps: .\run.ps1 default-build
|
||||
clone_depth: 1
|
||||
environment:
|
||||
global:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
test: 'off'
|
||||
deploy: 'off'
|
||||
os: Visual Studio 2017
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
|
||||
*.jpg binary
|
||||
*.png binary
|
||||
*.gif binary
|
||||
|
||||
*.cs text=auto diff=csharp
|
||||
*.vb text=auto
|
||||
*.resx text=auto
|
||||
*.c text=auto
|
||||
*.cpp text=auto
|
||||
*.cxx text=auto
|
||||
*.h text=auto
|
||||
*.hxx text=auto
|
||||
*.py text=auto
|
||||
*.rb text=auto
|
||||
*.java text=auto
|
||||
*.html text=auto
|
||||
*.htm text=auto
|
||||
*.css text=auto
|
||||
*.scss text=auto
|
||||
*.sass text=auto
|
||||
*.less text=auto
|
||||
*.js text=auto
|
||||
*.lisp text=auto
|
||||
*.clj text=auto
|
||||
*.sql text=auto
|
||||
*.php text=auto
|
||||
*.lua text=auto
|
||||
*.m text=auto
|
||||
*.asm text=auto
|
||||
*.erl text=auto
|
||||
*.fs text=auto
|
||||
*.fsx text=auto
|
||||
*.hs text=auto
|
||||
|
||||
*.csproj text=auto
|
||||
*.vbproj text=auto
|
||||
*.fsproj text=auto
|
||||
*.dbproj text=auto
|
||||
*.sln text=auto eol=crlf
|
||||
|
||||
*.sh eol=lf
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
[Oo]bj/
|
||||
[Bb]in/
|
||||
TestResults/
|
||||
.nuget/
|
||||
_ReSharper.*/
|
||||
packages/
|
||||
artifacts/
|
||||
PublishProfiles/
|
||||
*.user
|
||||
*.suo
|
||||
*.cache
|
||||
*.docstates
|
||||
_ReSharper.*
|
||||
nuget.exe
|
||||
*net45.csproj
|
||||
*net451.csproj
|
||||
*k10.csproj
|
||||
*.psess
|
||||
*.vsp
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*DS_Store
|
||||
*.ncrunchsolution
|
||||
*.*sdf
|
||||
*.ipch
|
||||
*.sln.ide
|
||||
node_modules
|
||||
*.sln.ide
|
||||
project.lock.json
|
||||
.vs/
|
||||
.vscode/
|
||||
launchSettings.json
|
||||
.build/
|
||||
.testPublish/
|
||||
global.json
|
||||
|
||||
# Rider and friends
|
||||
.idea/
|
||||
27
.travis.yml
27
.travis.yml
|
|
@ -1,27 +0,0 @@
|
|||
language: csharp
|
||||
sudo: false
|
||||
dist: trusty
|
||||
env:
|
||||
global:
|
||||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
mono: none
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
osx_image: xcode8.2
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libunwind8
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^release\/.*$/
|
||||
- /^(.*\/)?ci-.*$/
|
||||
before_install:
|
||||
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s
|
||||
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
|
||||
/usr/local/lib/; fi
|
||||
script:
|
||||
- ./build.sh
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
trigger:
|
||||
- master
|
||||
- release/*
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: buildtools
|
||||
type: git
|
||||
name: aspnet-BuildTools
|
||||
ref: refs/heads/master
|
||||
|
||||
phases:
|
||||
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
trigger:
|
||||
- master
|
||||
- release/*
|
||||
|
||||
# See https://github.com/aspnet/BuildTools
|
||||
resources:
|
||||
repositories:
|
||||
- repository: buildtools
|
||||
type: github
|
||||
endpoint: DotNet-Bot GitHub Connection
|
||||
name: aspnet/BuildTools
|
||||
ref: refs/heads/master
|
||||
|
||||
phases:
|
||||
- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools
|
||||
parameters:
|
||||
agentOs: Windows
|
||||
beforeBuild:
|
||||
- script: sqllocaldb start
|
||||
displayName: Start LocalDB
|
||||
|
||||
- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools
|
||||
parameters:
|
||||
agentOs: macOS
|
||||
|
||||
- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools
|
||||
parameters:
|
||||
agentOs: Linux
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Contributing
|
||||
======
|
||||
|
||||
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/AspNetCore/blob/master/CONTRIBUTING.md) in the AspNetCore repo.
|
||||
|
|
@ -1,410 +0,0 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26923.0
|
||||
MinimumVisualStudioVersion = 15.0.26730.03
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{509A6F36-AD80-4A18-B5B1-717D38DFF29D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{ACAA0157-A8C4-4152-93DE-90CCDF304087}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WelcomePageSample", "samples\WelcomePageSample\WelcomePageSample.csproj", "{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics", "src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj", "{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeveloperExceptionPageSample", "samples\DeveloperExceptionPageSample\DeveloperExceptionPageSample.csproj", "{589AC17F-9455-4764-8F82-FCD2AE58DA14}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2AF90579-B118-4583-AE88-672EFACB5BC4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics.Tests", "test\Microsoft.AspNetCore.Diagnostics.Tests\Microsoft.AspNetCore.Diagnostics.Tests.csproj", "{994351B4-7B2A-4139-8B72-72C5BB5CC618}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExceptionHandlerSample", "samples\ExceptionHandlerSample\ExceptionHandlerSample.csproj", "{427CDB36-78B0-4583-9EBC-7F283DE60355}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore", "src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj", "{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.Tests", "test\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.Tests\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.Tests.csproj", "{5486117B-A742-49E0-94FC-12B76F061803}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics.Elm", "src\Microsoft.AspNetCore.Diagnostics.Elm\Microsoft.AspNetCore.Diagnostics.Elm.csproj", "{624B0019-956A-4157-B008-270C5B229553}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatusCodePagesSample", "samples\StatusCodePagesSample\StatusCodePagesSample.csproj", "{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics.Abstractions", "src\Microsoft.AspNetCore.Diagnostics.Abstractions\Microsoft.AspNetCore.Diagnostics.Abstractions.csproj", "{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElmPageSample", "samples\ElmPageSample\ElmPageSample.csproj", "{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseErrorPageSample", "samples\DatabaseErrorPageSample\DatabaseErrorPageSample.csproj", "{FF7F11A1-14E7-4948-A853-2487D99DE0C6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.MiddlewareAnalysis", "src\Microsoft.AspNetCore.MiddlewareAnalysis\Microsoft.AspNetCore.MiddlewareAnalysis.csproj", "{C2DEDD37-D1EB-4819-9A9C-475E37A52358}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiddlewareAnalysisSample", "samples\MiddlewareAnalysisSample\MiddlewareAnalysisSample.csproj", "{95981429-F212-44E1-83AA-32DA9E2A517C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.MiddlewareAnalysis.Tests", "test\Microsoft.AspNetCore.MiddlewareAnalysis.Tests\Microsoft.AspNetCore.MiddlewareAnalysis.Tests.csproj", "{B0166AED-738F-42EE-AF4D-C487C8B21521}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassLibraryWithPortablePdbs", "test\ClassLibraryWithPortablePdbs\ClassLibraryWithPortablePdbs.csproj", "{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Diagnostics.EFCore.FunctionalTests", "test\Diagnostics.EFCore.FunctionalTests\Diagnostics.EFCore.FunctionalTests.csproj", "{043C5272-D7F7-4DB1-830F-5DC93CC0878E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Diagnostics.FunctionalTests", "test\Diagnostics.FunctionalTests\Diagnostics.FunctionalTests.csproj", "{C142A666-D932-4E0D-8D18-5B08944C1077}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions", "src\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj", "{0D103C24-B9E8-468A-B113-509FCFEF7B45}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagnostics.HealthChecks", "src\Microsoft.Extensions.Diagnostics.HealthChecks\Microsoft.Extensions.Diagnostics.HealthChecks.csproj", "{F285F000-9342-4A01-9706-BAB2B97B4F97}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Diagnostics.HealthChecks", "src\Microsoft.AspNetCore.Diagnostics.HealthChecks\Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj", "{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecksSample", "samples\HealthChecksSample\HealthChecksSample.csproj", "{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests", "test\Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests\Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests.csproj", "{E718CE19-23CC-427F-B06E-B866E9A35924}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Diagnostics.HealthChecks.Tests", "test\Microsoft.Extensions.Diagnostics.HealthChecks.Tests\Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj", "{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore", "src\Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore\Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.csproj", "{61F8B71C-4BDA-431C-9485-743D619ACF9A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests", "test\Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests\Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests.csproj", "{4416D921-0E43-496D-9156-D7EAA9CB8DD3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5486117B-A742-49E0-94FC-12B76F061803}.Release|x86.Build.0 = Release|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{624B0019-956A-4157-B008-270C5B229553}.Release|x86.Build.0 = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129}.Release|x86.Build.0 = Release|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.Build.0 = Release|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0}.Release|x86.Build.0 = Release|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{C5F59CBA-DF2D-4983-8CBB-11B6AF21B416} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{68A1F0E1-ECCE-46D1-B20F-C43EE5B097DE} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{589AC17F-9455-4764-8F82-FCD2AE58DA14} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{994351B4-7B2A-4139-8B72-72C5BB5CC618} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{427CDB36-78B0-4583-9EBC-7F283DE60355} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{4F5A6A72-FFE4-49C4-B4C6-58132CFCB9FE} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{5486117B-A742-49E0-94FC-12B76F061803} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{624B0019-956A-4157-B008-270C5B229553} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{CC1F5841-FE10-4DDB-8477-C4DE92BA759F} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{FF7F11A1-14E7-4948-A853-2487D99DE0C6} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{C2DEDD37-D1EB-4819-9A9C-475E37A52358} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{95981429-F212-44E1-83AA-32DA9E2A517C} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{B0166AED-738F-42EE-AF4D-C487C8B21521} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{AA3661A1-CE8D-4597-ADFD-A5A30834E5D0} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{043C5272-D7F7-4DB1-830F-5DC93CC0878E} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{C142A666-D932-4E0D-8D18-5B08944C1077} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{0D103C24-B9E8-468A-B113-509FCFEF7B45} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{F285F000-9342-4A01-9706-BAB2B97B4F97} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{1B2B1EF4-9066-4F38-ADCF-D05C6423E21C} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{3B4E60F6-E42D-496E-B96F-71A11DABAEE7} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
|
||||
{E718CE19-23CC-427F-B06E-B866E9A35924} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{3783E8E4-2E96-4987-A83A-0CCCAF4891C1} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
{61F8B71C-4BDA-431C-9485-743D619ACF9A} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
|
||||
{4416D921-0E43-496D-9156-D7EAA9CB8DD3} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D915AA7B-4ADE-4BAC-AF65-1E800D3F3580}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<Project>
|
||||
<Import
|
||||
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
|
||||
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
|
||||
|
||||
<Import Project="version.props" />
|
||||
<Import Project="build\dependencies.props" />
|
||||
<Import Project="build\sources.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Product>Microsoft ASP.NET Core</Product>
|
||||
<RepositoryUrl>https://github.com/aspnet/Diagnostics</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">$(MicrosoftNETCoreAppPackageVersion)</RuntimeFrameworkVersion>
|
||||
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
201
LICENSE.txt
201
LICENSE.txt
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) .NET Foundation and Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<!-- Restore sources should be defined in build/sources.props. -->
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"Default": {
|
||||
"rules": [
|
||||
"DefaultCompositeRule"
|
||||
]
|
||||
}
|
||||
}
|
||||
11
README.md
11
README.md
|
|
@ -1,11 +0,0 @@
|
|||
ASP.NET Core Diagnostics
|
||||
================
|
||||
|
||||
AppVeyor: [](https://ci.appveyor.com/project/aspnetci/Diagnostics/branch/dev)
|
||||
|
||||
Travis: [](https://travis-ci.org/aspnet/Diagnostics)
|
||||
|
||||
Diagnostics middleware for reporting info and handling exceptions and errors in ASP.NET Core, and diagnosing Entity Framework Core migrations errors.
|
||||
|
||||
|
||||
This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
@ECHO OFF
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
|
||||
8
build.sh
8
build.sh
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs)
|
||||
chmod +x "$DIR/run.sh"; sync
|
||||
"$DIR/run.sh" default-build "$@"
|
||||
BIN
build/Key.snk
BIN
build/Key.snk
Binary file not shown.
|
|
@ -1,51 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Package Versions">
|
||||
<InternalAspNetCoreSdkPackageVersion>3.0.0-build-20181116.1</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
|
||||
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
|
||||
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreServerKestrelPackageVersion>
|
||||
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreStaticFilesPackageVersion>
|
||||
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreTestHostPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview-181113-11</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>3.0.0-preview-181109-02</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>3.0.0-preview-181109-02</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>3.0.0-preview-181109-02</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>3.0.0-alpha1-10742</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsRazorViewsSourcesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsRazorViewsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsStackTraceSourcesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsStackTraceSourcesPackageVersion>
|
||||
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||
<MicrosoftNETCoreAppPackageVersion>3.0.0-preview1-26907-05</MicrosoftNETCoreAppPackageVersion>
|
||||
<MicrosoftNetHttpHeadersPackageVersion>3.0.0-alpha1-10742</MicrosoftNetHttpHeadersPackageVersion>
|
||||
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
|
||||
<MoqPackageVersion>4.10.0</MoqPackageVersion>
|
||||
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
|
||||
<SystemDataSqlClientPackageVersion>4.6.0-preview1-26907-04</SystemDataSqlClientPackageVersion>
|
||||
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.6.0-preview1-26907-04</SystemDiagnosticsDiagnosticSourcePackageVersion>
|
||||
<SystemReflectionMetadataPackageVersion>1.7.0-preview1-26907-04</SystemReflectionMetadataPackageVersion>
|
||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
|
||||
<PropertyGroup Label="Package Versions: Pinned" />
|
||||
</Project>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="dependencies.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- These properties are use by the automation that updates dependencies.props -->
|
||||
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
|
||||
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreAppPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
||||
|
||||
<PropertyGroup Label="RestoreSources">
|
||||
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
|
||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
|
||||
$(RestoreSources);
|
||||
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||
</RestoreSources>
|
||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
||||
$(RestoreSources);
|
||||
https://api.nuget.org/v3/index.json;
|
||||
</RestoreSources>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
version:3.0.0-build-20181116.1
|
||||
commithash:9be7d79a8f7e0668f66e584aca1e962f45975511
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
|
||||
"channel": "master"
|
||||
}
|
||||
2
run.cmd
2
run.cmd
|
|
@ -1,2 +0,0 @@
|
|||
@ECHO OFF
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
|
||||
209
run.ps1
209
run.ps1
|
|
@ -1,209 +0,0 @@
|
|||
#!/usr/bin/env powershell
|
||||
#requires -version 4
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Executes KoreBuild commands.
|
||||
|
||||
.DESCRIPTION
|
||||
Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`.
|
||||
|
||||
.PARAMETER Command
|
||||
The KoreBuild command to run.
|
||||
|
||||
.PARAMETER Path
|
||||
The folder to build. Defaults to the folder containing this script.
|
||||
|
||||
.PARAMETER Channel
|
||||
The channel of KoreBuild to download. Overrides the value from the config file.
|
||||
|
||||
.PARAMETER DotNetHome
|
||||
The directory where .NET Core tools will be stored.
|
||||
|
||||
.PARAMETER ToolsSource
|
||||
The base url where build tools can be downloaded. Overrides the value from the config file.
|
||||
|
||||
.PARAMETER Update
|
||||
Updates KoreBuild to the latest version even if a lock file is present.
|
||||
|
||||
.PARAMETER Reinstall
|
||||
Re-installs KoreBuild
|
||||
|
||||
.PARAMETER ConfigFile
|
||||
The path to the configuration file that stores values. Defaults to korebuild.json.
|
||||
|
||||
.PARAMETER ToolsSourceSuffix
|
||||
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
|
||||
|
||||
.PARAMETER CI
|
||||
Sets up CI specific settings and variables.
|
||||
|
||||
.PARAMETER Arguments
|
||||
Arguments to be passed to the command
|
||||
|
||||
.NOTES
|
||||
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
|
||||
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
|
||||
|
||||
The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
|
||||
in the file are overridden by command line parameters.
|
||||
|
||||
.EXAMPLE
|
||||
Example config file:
|
||||
```json
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
|
||||
"channel": "master",
|
||||
"toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
|
||||
}
|
||||
```
|
||||
#>
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string]$Command,
|
||||
[string]$Path = $PSScriptRoot,
|
||||
[Alias('c')]
|
||||
[string]$Channel,
|
||||
[Alias('d')]
|
||||
[string]$DotNetHome,
|
||||
[Alias('s')]
|
||||
[string]$ToolsSource,
|
||||
[Alias('u')]
|
||||
[switch]$Update,
|
||||
[switch]$Reinstall,
|
||||
[string]$ToolsSourceSuffix,
|
||||
[string]$ConfigFile = $null,
|
||||
[switch]$CI,
|
||||
[Parameter(ValueFromRemainingArguments = $true)]
|
||||
[string[]]$Arguments
|
||||
)
|
||||
|
||||
Set-StrictMode -Version 2
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
|
||||
function Get-KoreBuild {
|
||||
|
||||
$lockFile = Join-Path $Path 'korebuild-lock.txt'
|
||||
|
||||
if (!(Test-Path $lockFile) -or $Update) {
|
||||
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
|
||||
}
|
||||
|
||||
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
||||
if (!$version) {
|
||||
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
|
||||
}
|
||||
$version = $version.TrimStart('version:').Trim()
|
||||
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
|
||||
|
||||
if ($Reinstall -and (Test-Path $korebuildPath)) {
|
||||
Remove-Item -Force -Recurse $korebuildPath
|
||||
}
|
||||
|
||||
if (!(Test-Path $korebuildPath)) {
|
||||
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
|
||||
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
|
||||
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||
|
||||
try {
|
||||
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
||||
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
|
||||
if (Get-Command -Name 'Microsoft.PowerShell.Archive\Expand-Archive' -ErrorAction Ignore) {
|
||||
# Use built-in commands where possible as they are cross-plat compatible
|
||||
Microsoft.PowerShell.Archive\Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
||||
}
|
||||
else {
|
||||
# Fallback to old approach for old installations of PowerShell
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
|
||||
throw
|
||||
}
|
||||
finally {
|
||||
Remove-Item $tmpfile -ErrorAction Ignore
|
||||
}
|
||||
}
|
||||
|
||||
return $korebuildPath
|
||||
}
|
||||
|
||||
function Join-Paths([string]$path, [string[]]$childPaths) {
|
||||
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
|
||||
return $path
|
||||
}
|
||||
|
||||
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
|
||||
if ($RemotePath -notlike 'http*') {
|
||||
Copy-Item $RemotePath $LocalPath
|
||||
return
|
||||
}
|
||||
|
||||
$retries = 10
|
||||
while ($retries -gt 0) {
|
||||
$retries -= 1
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
|
||||
return
|
||||
}
|
||||
catch {
|
||||
Write-Verbose "Request failed. $retries retries remaining"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Error "Download failed: '$RemotePath'."
|
||||
}
|
||||
|
||||
#
|
||||
# Main
|
||||
#
|
||||
|
||||
# Load configuration or set defaults
|
||||
|
||||
$Path = Resolve-Path $Path
|
||||
if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
|
||||
|
||||
if (Test-Path $ConfigFile) {
|
||||
try {
|
||||
$config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
|
||||
if ($config) {
|
||||
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
|
||||
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host -ForegroundColor Red $Error[0]
|
||||
Write-Error "$ConfigFile contains invalid JSON."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
if (!$DotNetHome) {
|
||||
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
|
||||
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
|
||||
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
|
||||
else { Join-Path $PSScriptRoot '.dotnet'}
|
||||
}
|
||||
|
||||
if (!$Channel) { $Channel = 'master' }
|
||||
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
|
||||
|
||||
# Execute
|
||||
|
||||
$korebuildPath = Get-KoreBuild
|
||||
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
|
||||
|
||||
try {
|
||||
Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI
|
||||
Invoke-KoreBuildCommand $Command @Arguments
|
||||
}
|
||||
finally {
|
||||
Remove-Module 'KoreBuild' -ErrorAction Ignore
|
||||
}
|
||||
256
run.sh
256
run.sh
|
|
@ -1,256 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
#
|
||||
# variables
|
||||
#
|
||||
|
||||
RESET="\033[0m"
|
||||
RED="\033[0;31m"
|
||||
YELLOW="\033[0;33m"
|
||||
MAGENTA="\033[0;95m"
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
|
||||
verbose=false
|
||||
update=false
|
||||
reinstall=false
|
||||
repo_path="$DIR"
|
||||
channel=''
|
||||
tools_source=''
|
||||
tools_source_suffix=''
|
||||
ci=false
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
__usage() {
|
||||
echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] <Arguments>...]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " command The command to be run."
|
||||
echo " <Arguments>... Arguments passed to the command. Variable number of arguments allowed."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --verbose Show verbose output."
|
||||
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
|
||||
echo " --config-file <FILE> The path to the configuration file that stores values. Defaults to korebuild.json."
|
||||
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
|
||||
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
|
||||
echo " -s|--tools-source|-ToolsSource <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
|
||||
echo " --tools-source-suffix|-ToolsSourceSuffix <SUFFIX> The suffix to append to tools-source. Useful for query strings."
|
||||
echo " -u|--update Update to the latest KoreBuild even if the lock file is present."
|
||||
echo " --reinstall Reinstall KoreBuild."
|
||||
echo " --ci Apply CI specific settings and environment variables."
|
||||
echo ""
|
||||
echo "Description:"
|
||||
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
|
||||
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
|
||||
|
||||
if [[ "${1:-}" != '--no-exit' ]]; then
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
get_korebuild() {
|
||||
local version
|
||||
local lock_file="$repo_path/korebuild-lock.txt"
|
||||
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
|
||||
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix"
|
||||
fi
|
||||
version="$(grep 'version:*' -m 1 "$lock_file")"
|
||||
if [[ "$version" == '' ]]; then
|
||||
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
|
||||
return 1
|
||||
fi
|
||||
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
|
||||
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
|
||||
|
||||
if [ "$reinstall" = true ] && [ -d "$korebuild_path" ]; then
|
||||
rm -rf "$korebuild_path"
|
||||
fi
|
||||
|
||||
{
|
||||
if [ ! -d "$korebuild_path" ]; then
|
||||
mkdir -p "$korebuild_path"
|
||||
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||
tmpfile="$(mktemp)"
|
||||
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
|
||||
if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then
|
||||
unzip -q -d "$korebuild_path" "$tmpfile"
|
||||
fi
|
||||
rm "$tmpfile" || true
|
||||
fi
|
||||
|
||||
source "$korebuild_path/KoreBuild.sh"
|
||||
} || {
|
||||
if [ -d "$korebuild_path" ]; then
|
||||
echo "Cleaning up after failed installation"
|
||||
rm -rf "$korebuild_path" || true
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
__error() {
|
||||
echo -e "${RED}error: $*${RESET}" 1>&2
|
||||
}
|
||||
|
||||
__warn() {
|
||||
echo -e "${YELLOW}warning: $*${RESET}"
|
||||
}
|
||||
|
||||
__machine_has() {
|
||||
hash "$1" > /dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
__get_remote_file() {
|
||||
local remote_path=$1
|
||||
local local_path=$2
|
||||
local remote_path_suffix=$3
|
||||
|
||||
if [[ "$remote_path" != 'http'* ]]; then
|
||||
cp "$remote_path" "$local_path"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local failed=false
|
||||
if __machine_has wget; then
|
||||
wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
|
||||
else
|
||||
failed=true
|
||||
fi
|
||||
|
||||
if [ "$failed" = true ] && __machine_has curl; then
|
||||
failed=false
|
||||
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
|
||||
fi
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
__error "Download failed: $remote_path" 1>&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# main
|
||||
#
|
||||
|
||||
command="${1:-}"
|
||||
shift
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-\?|-h|--help)
|
||||
__usage --no-exit
|
||||
exit 0
|
||||
;;
|
||||
-c|--channel|-Channel)
|
||||
shift
|
||||
channel="${1:-}"
|
||||
[ -z "$channel" ] && __usage
|
||||
;;
|
||||
--config-file|-ConfigFile)
|
||||
shift
|
||||
config_file="${1:-}"
|
||||
[ -z "$config_file" ] && __usage
|
||||
if [ ! -f "$config_file" ]; then
|
||||
__error "Invalid value for --config-file. $config_file does not exist."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-d|--dotnet-home|-DotNetHome)
|
||||
shift
|
||||
DOTNET_HOME="${1:-}"
|
||||
[ -z "$DOTNET_HOME" ] && __usage
|
||||
;;
|
||||
--path|-Path)
|
||||
shift
|
||||
repo_path="${1:-}"
|
||||
[ -z "$repo_path" ] && __usage
|
||||
;;
|
||||
-s|--tools-source|-ToolsSource)
|
||||
shift
|
||||
tools_source="${1:-}"
|
||||
[ -z "$tools_source" ] && __usage
|
||||
;;
|
||||
--tools-source-suffix|-ToolsSourceSuffix)
|
||||
shift
|
||||
tools_source_suffix="${1:-}"
|
||||
[ -z "$tools_source_suffix" ] && __usage
|
||||
;;
|
||||
-u|--update|-Update)
|
||||
update=true
|
||||
;;
|
||||
--reinstall|-[Rr]einstall)
|
||||
reinstall=true
|
||||
;;
|
||||
--ci|-[Cc][Ii])
|
||||
ci=true
|
||||
;;
|
||||
--verbose|-Verbose)
|
||||
verbose=true
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if ! __machine_has unzip; then
|
||||
__error 'Missing required command: unzip'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! __machine_has curl && ! __machine_has wget; then
|
||||
__error 'Missing required command. Either wget or curl is required.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json"
|
||||
if [ -f "$config_file" ]; then
|
||||
if __machine_has jq ; then
|
||||
if jq '.' "$config_file" >/dev/null ; then
|
||||
config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")"
|
||||
config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")"
|
||||
else
|
||||
__error "$config_file contains invalid JSON."
|
||||
exit 1
|
||||
fi
|
||||
elif __machine_has python ; then
|
||||
if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
|
||||
config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
|
||||
config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
|
||||
else
|
||||
__error "$config_file contains invalid JSON."
|
||||
exit 1
|
||||
fi
|
||||
elif __machine_has python3 ; then
|
||||
if python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
|
||||
config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
|
||||
config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
|
||||
else
|
||||
__error "$config_file contains invalid JSON."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
__error 'Missing required command: jq or python. Could not parse the JSON file.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
|
||||
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
|
||||
fi
|
||||
|
||||
[ -z "$channel" ] && channel='master'
|
||||
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
|
||||
|
||||
get_korebuild
|
||||
set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" "$ci"
|
||||
invoke_korebuild_command "$command" "$@"
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics.Elm\Microsoft.AspNetCore.Diagnostics.Elm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ElmPageSample
|
||||
{
|
||||
public class HelloWorldMiddleware
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public HelloWorldMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
|
||||
{
|
||||
_next = next;
|
||||
_logger = loggerFactory.CreateLogger<HelloWorldMiddleware>();
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
using (_logger.BeginScope("Scope1"))
|
||||
{
|
||||
_logger.LogDebug("Getting message");
|
||||
|
||||
httpContext.Response.ContentType = "text/html; charset=utf-8";
|
||||
await httpContext.Response.WriteAsync(
|
||||
"<html><body><h2>Hello World!</h2><a href=\"/Elm\">Elm Logs</a></body></html>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ElmPageSample
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddElm(elmOptions =>
|
||||
{
|
||||
elmOptions.Filter = (loggerName, loglevel) => loglevel == LogLevel.Debug;
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseElmPage();
|
||||
|
||||
app.UseElmCapture();
|
||||
|
||||
app.UseMiddleware<HelloWorldMiddleware>();
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseIISIntegration()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
You've reached the static error page.<br /><br />
|
||||
<a href="/">Home</a><br />
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Used in our tests -->
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLinePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsConfigurationJsonPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion)" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="$(SystemDataSqlClientPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics.HealthChecks\Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore\Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.MiddlewareAnalysis\Microsoft.AspNetCore.MiddlewareAnalysis.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="$(MicrosoftExtensionsDiagnosticAdapterPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics\Microsoft.AspNetCore.Diagnostics.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="$(MicrosoftAspNetCoreServerIISIntegrationPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="..\Directory.Build.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class ActivityContext
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public HttpInfo HttpInfo { get; set; }
|
||||
|
||||
public ScopeNode Root { get; set; }
|
||||
|
||||
public DateTimeOffset Time { get; set; }
|
||||
|
||||
public bool IsCollapsed { get; set; }
|
||||
|
||||
public bool RepresentsScope { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables the Elm logging service.
|
||||
/// </summary>
|
||||
public class ElmCaptureMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ElmOptions _options;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ElmCaptureMiddleware(RequestDelegate next, ILoggerFactory factory, IOptions<ElmOptions> options)
|
||||
{
|
||||
_next = next;
|
||||
_options = options.Value;
|
||||
_logger = factory.CreateLogger<ElmCaptureMiddleware>();
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
using (RequestIdentifier.Ensure(context))
|
||||
{
|
||||
var requestId = context.Features.Get<IHttpRequestIdentifierFeature>().TraceIdentifier;
|
||||
using (_logger.BeginScope("Request: {RequestId}", requestId))
|
||||
{
|
||||
try
|
||||
{
|
||||
ElmScope.Current.Context.HttpInfo = GetHttpInfo(context);
|
||||
await _next(context);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ElmScope.Current.Context.HttpInfo.StatusCode = context.Response.StatusCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes the info from the given HttpContext and copies it to an HttpInfo object
|
||||
/// </summary>
|
||||
/// <returns>The HttpInfo for the current elm context</returns>
|
||||
private static HttpInfo GetHttpInfo(HttpContext context)
|
||||
{
|
||||
return new HttpInfo()
|
||||
{
|
||||
RequestID = context.Features.Get<IHttpRequestIdentifierFeature>().TraceIdentifier,
|
||||
Host = context.Request.Host,
|
||||
ContentType = context.Request.ContentType,
|
||||
Path = context.Request.Path,
|
||||
Scheme = context.Request.Scheme,
|
||||
StatusCode = context.Response.StatusCode,
|
||||
User = context.User,
|
||||
Method = context.Request.Method,
|
||||
Protocol = context.Request.Protocol,
|
||||
Headers = context.Request.Headers,
|
||||
Query = context.Request.QueryString,
|
||||
Cookies = context.Request.Cookies
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class ElmExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables the Elm logging service, which can be accessed via the <see cref="ElmPageMiddleware"/>.
|
||||
/// </summary>
|
||||
public static IApplicationBuilder UseElmCapture(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
// add the elm provider to the factory here so the logger can start capturing logs immediately
|
||||
var factory = app.ApplicationServices.GetRequiredService<ILoggerFactory>() as LoggerFactory;
|
||||
if (factory != null)
|
||||
{
|
||||
var provider = app.ApplicationServices.GetRequiredService<ElmLoggerProvider>();
|
||||
factory.AddProvider(provider);
|
||||
}
|
||||
|
||||
return app.UseMiddleware<ElmCaptureMiddleware>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables viewing logs captured by the <see cref="ElmCaptureMiddleware"/>.
|
||||
/// </summary>
|
||||
public static IApplicationBuilder UseElmPage(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<ElmPageMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class ElmLogger : ILogger
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly ElmOptions _options;
|
||||
private readonly ElmStore _store;
|
||||
|
||||
public ElmLogger(string name, ElmOptions options, ElmStore store)
|
||||
{
|
||||
_name = name;
|
||||
_options = options;
|
||||
_store = store;
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
|
||||
Func<TState, Exception, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel) || (state == null && exception == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
LogInfo info = new LogInfo()
|
||||
{
|
||||
ActivityContext = GetCurrentActivityContext(),
|
||||
Name = _name,
|
||||
EventID = eventId.Id,
|
||||
Severity = logLevel,
|
||||
Exception = exception,
|
||||
State = state,
|
||||
Message = formatter == null ? state.ToString() : formatter(state, exception),
|
||||
Time = DateTimeOffset.UtcNow
|
||||
};
|
||||
if (ElmScope.Current != null)
|
||||
{
|
||||
ElmScope.Current.Node.Messages.Add(info);
|
||||
}
|
||||
// The log does not belong to any scope - create a new context for it
|
||||
else
|
||||
{
|
||||
var context = GetNewActivityContext();
|
||||
context.RepresentsScope = false; // mark as a non-scope log
|
||||
context.Root = new ScopeNode();
|
||||
context.Root.Messages.Add(info);
|
||||
_store.AddActivity(context);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return _options.Filter(_name, logLevel);
|
||||
}
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state)
|
||||
{
|
||||
var scope = new ElmScope(_name, state);
|
||||
scope.Context = ElmScope.Current?.Context ?? GetNewActivityContext();
|
||||
return ElmScope.Push(scope, _store);
|
||||
}
|
||||
|
||||
private ActivityContext GetNewActivityContext()
|
||||
{
|
||||
return new ActivityContext()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Time = DateTimeOffset.UtcNow,
|
||||
RepresentsScope = true
|
||||
};
|
||||
}
|
||||
|
||||
private ActivityContext GetCurrentActivityContext()
|
||||
{
|
||||
return ElmScope.Current?.Context ?? GetNewActivityContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class ElmLoggerProvider : ILoggerProvider
|
||||
{
|
||||
private readonly ElmStore _store;
|
||||
private readonly ElmOptions _options;
|
||||
|
||||
public ElmLoggerProvider(ElmStore store, IOptions<ElmOptions> options)
|
||||
{
|
||||
if (store == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(store));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
_store = store;
|
||||
_options = options.Value;
|
||||
}
|
||||
|
||||
public ILogger CreateLogger(string name)
|
||||
{
|
||||
return new ElmLogger(name, _options, _store);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for ElmMiddleware
|
||||
/// </summary>
|
||||
public class ElmOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the path to view the logs.
|
||||
/// </summary>
|
||||
public PathString Path { get; set; } = new PathString("/Elm");
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether log statements should be logged based on the name of the logger
|
||||
/// and the <see cref="M:LogLevel"/> of the message.
|
||||
/// </summary>
|
||||
public Func<string, LogLevel, bool> Filter { get; set; } = (name, level) => true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm.RazorViews;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables viewing logs captured by the <see cref="ElmCaptureMiddleware"/>.
|
||||
/// </summary>
|
||||
public class ElmPageMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ElmOptions _options;
|
||||
private readonly ElmStore _store;
|
||||
|
||||
public ElmPageMiddleware(RequestDelegate next, IOptions<ElmOptions> options, ElmStore store)
|
||||
{
|
||||
_next = next;
|
||||
_options = options.Value;
|
||||
_store = store;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (!context.Request.Path.StartsWithSegments(_options.Path))
|
||||
{
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
var t = await ParseParams(context);
|
||||
var options = t.Item1;
|
||||
var redirect = t.Item2;
|
||||
if (redirect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (context.Request.Path == _options.Path)
|
||||
{
|
||||
RenderMainLogPage(options, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderDetailsPage(options, context);
|
||||
}
|
||||
}
|
||||
|
||||
private async void RenderMainLogPage(ViewOptions options, HttpContext context)
|
||||
{
|
||||
var model = new LogPageModel()
|
||||
{
|
||||
Activities = _store.GetActivities(),
|
||||
Options = options,
|
||||
Path = _options.Path
|
||||
};
|
||||
var logPage = new LogPage(model);
|
||||
|
||||
await logPage.ExecuteAsync(context);
|
||||
}
|
||||
|
||||
private async void RenderDetailsPage(ViewOptions options, HttpContext context)
|
||||
{
|
||||
var parts = context.Request.Path.Value.Split('/');
|
||||
var id = Guid.Empty;
|
||||
if (!Guid.TryParse(parts[parts.Length - 1], out id))
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
await context.Response.WriteAsync("Invalid Id");
|
||||
return;
|
||||
}
|
||||
var model = new DetailsPageModel()
|
||||
{
|
||||
Activity = _store.GetActivities().Where(a => a.Id == id).FirstOrDefault(),
|
||||
Options = options
|
||||
};
|
||||
var detailsPage = new DetailsPage(model);
|
||||
await detailsPage.ExecuteAsync(context);
|
||||
}
|
||||
|
||||
private async Task<Tuple<ViewOptions, bool>> ParseParams(HttpContext context)
|
||||
{
|
||||
var options = new ViewOptions()
|
||||
{
|
||||
MinLevel = LogLevel.Debug,
|
||||
NamePrefix = string.Empty
|
||||
};
|
||||
var isRedirect = false;
|
||||
|
||||
IFormCollection form = null;
|
||||
if (context.Request.HasFormContentType)
|
||||
{
|
||||
form = await context.Request.ReadFormAsync();
|
||||
}
|
||||
|
||||
if (form != null && form.ContainsKey("clear"))
|
||||
{
|
||||
_store.Clear();
|
||||
context.Response.Redirect(context.Request.PathBase.Add(_options.Path).ToString());
|
||||
isRedirect = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context.Request.Query.ContainsKey("level"))
|
||||
{
|
||||
var minLevel = options.MinLevel;
|
||||
if (Enum.TryParse<LogLevel>(context.Request.Query["level"], out minLevel))
|
||||
{
|
||||
options.MinLevel = minLevel;
|
||||
}
|
||||
}
|
||||
if (context.Request.Query.ContainsKey("name"))
|
||||
{
|
||||
var namePrefix = context.Request.Query["name"];
|
||||
options.NamePrefix = namePrefix;
|
||||
}
|
||||
}
|
||||
return Tuple.Create(options, isRedirect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class ElmScope
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly object _state;
|
||||
|
||||
public ElmScope(string name, object state)
|
||||
{
|
||||
_name = name;
|
||||
_state = state;
|
||||
}
|
||||
|
||||
public ActivityContext Context { get; set; }
|
||||
|
||||
public ElmScope Parent { get; set; }
|
||||
|
||||
public ScopeNode Node { get; set; }
|
||||
|
||||
private static AsyncLocal<ElmScope> _value = new AsyncLocal<ElmScope>();
|
||||
public static ElmScope Current
|
||||
{
|
||||
set
|
||||
{
|
||||
_value.Value = value;
|
||||
}
|
||||
get
|
||||
{
|
||||
return _value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public static IDisposable Push(ElmScope scope, ElmStore store)
|
||||
{
|
||||
if (scope == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(scope));
|
||||
}
|
||||
|
||||
if (store == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(store));
|
||||
}
|
||||
|
||||
var temp = Current;
|
||||
Current = scope;
|
||||
Current.Parent = temp;
|
||||
|
||||
Current.Node = new ScopeNode()
|
||||
{
|
||||
StartTime = DateTimeOffset.UtcNow,
|
||||
State = Current._state,
|
||||
Name = Current._name
|
||||
};
|
||||
|
||||
if (Current.Parent != null)
|
||||
{
|
||||
Current.Node.Parent = Current.Parent.Node;
|
||||
Current.Parent.Node.Children.Add(Current.Node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.Context.Root = Current.Node;
|
||||
store.AddActivity(Current.Context);
|
||||
}
|
||||
|
||||
return new DisposableAction(() =>
|
||||
{
|
||||
Current.Node.EndTime = DateTimeOffset.UtcNow;
|
||||
Current = Current.Parent;
|
||||
});
|
||||
}
|
||||
|
||||
private class DisposableAction : IDisposable
|
||||
{
|
||||
private Action _action;
|
||||
|
||||
public DisposableAction(Action action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_action != null)
|
||||
{
|
||||
_action.Invoke();
|
||||
_action = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for setting up Elm services in an <see cref="IServiceCollection" />.
|
||||
/// </summary>
|
||||
public static class ElmServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds error logging middleware services to the specified <see cref="IServiceCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
|
||||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
|
||||
public static IServiceCollection AddElm(this IServiceCollection services)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
services.AddOptions();
|
||||
services.TryAddSingleton<ElmStore>();
|
||||
services.TryAddSingleton<ElmLoggerProvider>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds error logging middleware services to the specified <see cref="IServiceCollection" />.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
|
||||
/// <param name="setupAction">An <see cref="Action{ElmOptions}"/> to configure the provided <see cref="ElmOptions"/>.</param>
|
||||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
|
||||
public static IServiceCollection AddElm(this IServiceCollection services, Action<ElmOptions> setupAction)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
if (setupAction == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(setupAction));
|
||||
}
|
||||
|
||||
services.AddElm();
|
||||
services.Configure(setupAction);
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class ElmStore
|
||||
{
|
||||
private const int Capacity = 200;
|
||||
|
||||
private LinkedList<ActivityContext> Activities { get; set; } = new LinkedList<ActivityContext>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns an IEnumerable of the contexts of the logs.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerable of <see cref="ActivityContext"/> objects where each context stores
|
||||
/// information about a top level scope.</returns>
|
||||
public IEnumerable<ActivityContext> GetActivities()
|
||||
{
|
||||
for (var context = Activities.First; context != null; context = context.Next)
|
||||
{
|
||||
if (!context.Value.IsCollapsed && CollapseActivityContext(context.Value))
|
||||
{
|
||||
Activities.Remove(context);
|
||||
}
|
||||
}
|
||||
return Activities;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new <see cref="ActivityContext"/> to the store.
|
||||
/// </summary>
|
||||
/// <param name="activity">The <see cref="ActivityContext"/> to be added to the store.</param>
|
||||
public void AddActivity(ActivityContext activity)
|
||||
{
|
||||
if (activity == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(activity));
|
||||
}
|
||||
|
||||
lock (Activities)
|
||||
{
|
||||
Activities.AddLast(activity);
|
||||
while (Count() > Capacity)
|
||||
{
|
||||
Activities.RemoveFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all activity contexts that have been stored.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
Activities.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the total number of logs in all activities in the store
|
||||
/// </summary>
|
||||
/// <returns>The total log count</returns>
|
||||
public int Count()
|
||||
{
|
||||
return Activities.Sum(a => Count(a.Root));
|
||||
}
|
||||
|
||||
private int Count(ScopeNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
var sum = node.Messages.Count;
|
||||
foreach (var child in node.Children)
|
||||
{
|
||||
sum += Count(child);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes any nodes on the context's scope tree that doesn't have any logs
|
||||
/// This may occur as a result of the filters turned on
|
||||
/// </summary>
|
||||
/// <param name="context">The context who's node should be condensed</param>
|
||||
/// <returns>true if the node has been condensed to null, false otherwise</returns>
|
||||
private bool CollapseActivityContext(ActivityContext context)
|
||||
{
|
||||
context.Root = CollapseHelper(context.Root);
|
||||
context.IsCollapsed = true;
|
||||
return context.Root == null;
|
||||
}
|
||||
|
||||
private ScopeNode CollapseHelper(ScopeNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
for (int i = 0; i < node.Children.Count; i++)
|
||||
{
|
||||
node.Children[i] = CollapseHelper(node.Children[i]);
|
||||
}
|
||||
node.Children.RemoveAll(c => c == null);
|
||||
if (node.Children.Count == 0 && node.Messages.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class HttpInfo
|
||||
{
|
||||
public string RequestID { get; set; }
|
||||
|
||||
public HostString Host { get; set; }
|
||||
|
||||
public PathString Path { get; set; }
|
||||
|
||||
public string ContentType { get; set; }
|
||||
|
||||
public string Scheme { get; set; }
|
||||
|
||||
public int StatusCode { get; set; }
|
||||
|
||||
public ClaimsPrincipal User { get; set; }
|
||||
|
||||
public string Method { get; set; }
|
||||
|
||||
public string Protocol { get; set; }
|
||||
|
||||
public IHeaderDictionary Headers { get; set; }
|
||||
|
||||
public QueryString Query { get; set; }
|
||||
|
||||
public IRequestCookieCollection Cookies { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
internal class HttpRequestIdentifierFeature : IHttpRequestIdentifierFeature
|
||||
{
|
||||
public string TraceIdentifier { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class LogInfo
|
||||
{
|
||||
public ActivityContext ActivityContext { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public object State { get; set; }
|
||||
|
||||
public Exception Exception { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public LogLevel Severity { get; set; }
|
||||
|
||||
public int EventID { get; set; }
|
||||
|
||||
public DateTimeOffset Time { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core Error Logging Middleware (ELM) to capture and display request logs.</Description>
|
||||
<VersionPrefix Condition="'$(ExperimentalVersionPrefix)' != ''">$(ExperimentalVersionPrefix)</VersionPrefix>
|
||||
<VersionSuffix Condition="'$(ExperimentalVersionSuffix)' != ''">$(ExperimentalVersionSuffix)</VersionSuffix>
|
||||
<VerifyVersion Condition="'$(ExperimentalVersionPrefix)' != ''">false</VerifyVersion>
|
||||
<PackageVersion Condition="'$(ExperimentalPackageVersion)' != ''">$(ExperimentalPackageVersion)</PackageVersion>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;diagnostics</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\shared\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.RazorViews.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsRazorViewsSourcesPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
internal class RequestIdentifier : IDisposable
|
||||
{
|
||||
private readonly bool _addedFeature;
|
||||
private readonly bool _updatedIdentifier;
|
||||
private readonly string _originalIdentifierValue;
|
||||
private readonly HttpContext _context;
|
||||
private readonly IHttpRequestIdentifierFeature _feature;
|
||||
|
||||
private RequestIdentifier(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
_feature = context.Features.Get<IHttpRequestIdentifierFeature>();
|
||||
|
||||
if (_feature == null)
|
||||
{
|
||||
_feature = new HttpRequestIdentifierFeature()
|
||||
{
|
||||
TraceIdentifier = Guid.NewGuid().ToString()
|
||||
};
|
||||
context.Features.Set(_feature);
|
||||
_addedFeature = true;
|
||||
}
|
||||
else if (string.IsNullOrEmpty(_feature.TraceIdentifier))
|
||||
{
|
||||
_originalIdentifierValue = _feature.TraceIdentifier;
|
||||
_feature.TraceIdentifier = Guid.NewGuid().ToString();
|
||||
_updatedIdentifier = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static IDisposable Ensure(HttpContext context)
|
||||
{
|
||||
return new RequestIdentifier(context);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_addedFeature)
|
||||
{
|
||||
_context.Features.Set<IHttpRequestIdentifierFeature>(null);
|
||||
}
|
||||
else if (_updatedIdentifier)
|
||||
{
|
||||
_feature.TraceIdentifier = _originalIdentifierValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
public class ScopeNode
|
||||
{
|
||||
public ScopeNode Parent { get; set; }
|
||||
|
||||
public List<ScopeNode> Children { get; private set; } = new List<ScopeNode>();
|
||||
|
||||
public List<LogInfo> Messages { get; private set; } = new List<LogInfo>();
|
||||
|
||||
public DateTimeOffset StartTime { get; set; }
|
||||
|
||||
public DateTimeOffset EndTime { get; set; }
|
||||
|
||||
public object State { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for viewing elm logs.
|
||||
/// </summary>
|
||||
public class ViewOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum <see cref="LogLevel"/> of logs shown on the elm page.
|
||||
/// </summary>
|
||||
public LogLevel MinLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The prefix for the logger names of logs shown on the elm page.
|
||||
/// </summary>
|
||||
public string NamePrefix { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,541 +0,0 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm.RazorViews
|
||||
{
|
||||
#line hidden
|
||||
#line 1 "DetailsPage.cshtml"
|
||||
using System;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
using System.Threading.Tasks;
|
||||
#line 2 "DetailsPage.cshtml"
|
||||
using System.Globalization;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 3 "DetailsPage.cshtml"
|
||||
using System.Linq;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 4 "DetailsPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 5 "DetailsPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm.RazorViews;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 6 "DetailsPage.cshtml"
|
||||
using Microsoft.Extensions.RazorViews;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 7 "DetailsPage.cshtml"
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
internal class DetailsPage : Microsoft.Extensions.RazorViews.BaseView
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
public async override global::System.Threading.Tasks.Task ExecuteAsync()
|
||||
{
|
||||
WriteLiteral("\r\n");
|
||||
#line 86 "DetailsPage.cshtml"
|
||||
|
||||
Response.ContentType = "text/html; charset=utf-8";
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=""utf-8"" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src=""http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js""></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Arial, Helvtica, sans-serif;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Segoe UI', Helvetica, sans-serif;
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.critical {
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.information {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.debug {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: orange;
|
||||
} body {
|
||||
font-size: 0.9em;
|
||||
width: 90%;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0px;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid black;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
");
|
||||
WriteLiteral(@"
|
||||
th {
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#headerTable, #cookieTable {
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#headerTd {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
#label {
|
||||
width: 20%;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
#logs{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#logs>tbody>tr>td {
|
||||
border-right: 1px dashed lightgray;
|
||||
}
|
||||
|
||||
#logs>thead>tr>th {
|
||||
border: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
");
|
||||
#line 194 "DetailsPage.cshtml"
|
||||
|
||||
var context = Model.Activity?.HttpInfo;
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" ");
|
||||
#line 197 "DetailsPage.cshtml"
|
||||
if (context != null)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <h2 id=\"requestHeader\">Request Details</h2>\r\n <table id=\"requestDetails\">\r\n <colgroup><col id=\"label\" /><col /></colgroup>\r\n\r\n <tr>\r\n <th>Path</th>\r\n <td>");
|
||||
#line 205 "DetailsPage.cshtml"
|
||||
Write(context.Path);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Host</th>\r\n <td>");
|
||||
#line 209 "DetailsPage.cshtml"
|
||||
Write(context.Host);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Content Type</th>\r\n <td>");
|
||||
#line 213 "DetailsPage.cshtml"
|
||||
Write(context.ContentType);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Method</th>\r\n <td>");
|
||||
#line 217 "DetailsPage.cshtml"
|
||||
Write(context.Method);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Protocol</th>\r\n <td>");
|
||||
#line 221 "DetailsPage.cshtml"
|
||||
Write(context.Protocol);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Headers</th>
|
||||
<td id=""headerTd"">
|
||||
<table id=""headerTable"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
");
|
||||
#line 234 "DetailsPage.cshtml"
|
||||
foreach (var header in context.Headers)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
#line 237 "DetailsPage.cshtml"
|
||||
Write(header.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 238 "DetailsPage.cshtml"
|
||||
Write(string.Join(";", header.Value));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
#line 240 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </tbody>\r\n </table>\r\n </td>\r\n </tr>\r\n <tr>\r\n <th>Status Code</th>\r\n <td>");
|
||||
#line 247 "DetailsPage.cshtml"
|
||||
Write(context.StatusCode);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>User</th>\r\n <td>");
|
||||
#line 251 "DetailsPage.cshtml"
|
||||
Write(context.User.Identity.Name);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Claims</th>\r\n <td>\r\n");
|
||||
#line 256 "DetailsPage.cshtml"
|
||||
if (context.User.Claims.Any())
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@" <table id=""claimsTable"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Issuer</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
");
|
||||
#line 266 "DetailsPage.cshtml"
|
||||
foreach (var claim in context.User.Claims)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
#line 269 "DetailsPage.cshtml"
|
||||
Write(claim.Issuer);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 270 "DetailsPage.cshtml"
|
||||
Write(claim.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
#line 272 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </tbody>\r\n </table>\r\n");
|
||||
#line 275 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </td>\r\n </tr>\r\n <tr>\r\n <th>Scheme</th>\r\n <td>");
|
||||
#line 280 "DetailsPage.cshtml"
|
||||
Write(context.Scheme);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Query</th>\r\n <td>");
|
||||
#line 284 "DetailsPage.cshtml"
|
||||
Write(context.Query.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Cookies</th>\r\n <td>\r\n");
|
||||
#line 289 "DetailsPage.cshtml"
|
||||
if (context.Cookies.Any())
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@" <table id=""cookieTable"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
");
|
||||
#line 299 "DetailsPage.cshtml"
|
||||
foreach (var cookie in context.Cookies)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
#line 302 "DetailsPage.cshtml"
|
||||
Write(cookie.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 303 "DetailsPage.cshtml"
|
||||
Write(string.Join(";", cookie.Value));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
#line 305 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </tbody>\r\n </table>\r\n");
|
||||
#line 308 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </td>\r\n </tr>\r\n </table>\r\n");
|
||||
#line 312 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <h2>Logs</h2>\r\n <form method=\"get\">\r\n <select name=\"level\">\r\n");
|
||||
#line 316 "DetailsPage.cshtml"
|
||||
foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 8857, "\"", 8877, 1);
|
||||
#line 321 "DetailsPage.cshtml"
|
||||
WriteAttributeValue("", 8865, severityInt, 8865, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(" selected=\"selected\">");
|
||||
#line 321 "DetailsPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 322 "DetailsPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 9006, "\"", 9026, 1);
|
||||
#line 325 "DetailsPage.cshtml"
|
||||
WriteAttributeValue("", 9014, severityInt, 9014, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 325 "DetailsPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 326 "DetailsPage.cshtml"
|
||||
}
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </select>\r\n <input type=\"text\" name=\"name\"");
|
||||
BeginWriteAttribute("value", " value=\"", 9139, "\"", 9172, 1);
|
||||
#line 329 "DetailsPage.cshtml"
|
||||
WriteAttributeValue("", 9147, Model.Options.NamePrefix, 9147, 25, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(@" />
|
||||
<input type=""submit"" value=""filter"" />
|
||||
</form>
|
||||
<table id=""logs"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
<th>Severity</th>
|
||||
<th>Name</th>
|
||||
<th>State</th>
|
||||
<th>Error</th>
|
||||
</tr>
|
||||
</thead>
|
||||
");
|
||||
#line 343 "DetailsPage.cshtml"
|
||||
Write(Traverse(Model.Activity.Root));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@"
|
||||
</table>
|
||||
<script type=""text/javascript"">
|
||||
$(document).ready(function () {
|
||||
$(""#requestHeader"").click(function () {
|
||||
$(""#requestDetails"").toggle();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 10 "DetailsPage.cshtml"
|
||||
|
||||
public DetailsPage(DetailsPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DetailsPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
PushWriter(writer);
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
Write(string.Format("{0:MM/dd/yy}", log.Time));
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
Write(string.Format("{0:H:mm:ss}", log.Time));
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteral($"</td>\r\n <td class=\"{severity}\">");
|
||||
Write(log.Severity);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Name}\">");
|
||||
Write(log.Name);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Message}\""+
|
||||
"class=\"logState\" width=\"100px\">");
|
||||
Write(log.Message);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Exception}\">");
|
||||
Write(log.Exception);
|
||||
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
PopWriter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
LogRow(node.Messages[messageIndex]);
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Traverse(node.Children[childIndex]);
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
LogRow(node.Messages[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
Traverse(node.Children[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
@using System
|
||||
@using System.Globalization
|
||||
@using System.Linq
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm.RazorViews
|
||||
@using Microsoft.Extensions.RazorViews
|
||||
@using Microsoft.Extensions.Logging
|
||||
|
||||
@functions
|
||||
{
|
||||
public DetailsPage(DetailsPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DetailsPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
PushWriter(writer);
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
Write(string.Format("{0:MM/dd/yy}", log.Time));
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
Write(string.Format("{0:H:mm:ss}", log.Time));
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteral($"</td>\r\n <td class=\"{severity}\">");
|
||||
Write(log.Severity);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Name}\">");
|
||||
Write(log.Name);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Message}\""+
|
||||
"class=\"logState\" width=\"100px\">");
|
||||
Write(log.Message);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Exception}\">");
|
||||
Write(log.Exception);
|
||||
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
PopWriter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
LogRow(node.Messages[messageIndex]);
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Traverse(node.Children[childIndex]);
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
LogRow(node.Messages[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
Traverse(node.Children[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@{
|
||||
Response.ContentType = "text/html; charset=utf-8";
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js"></script>
|
||||
<style>
|
||||
<%$ include: Shared.css %> <%$ include: DetailsPage.css %>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
@{
|
||||
var context = Model.Activity?.HttpInfo;
|
||||
}
|
||||
@if (context != null)
|
||||
{
|
||||
<h2 id="requestHeader">Request Details</h2>
|
||||
<table id="requestDetails">
|
||||
<colgroup><col id="label" /><col /></colgroup>
|
||||
|
||||
<tr>
|
||||
<th>Path</th>
|
||||
<td>@context.Path</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Host</th>
|
||||
<td>@context.Host</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Content Type</th>
|
||||
<td>@context.ContentType</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<td>@context.Method</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Protocol</th>
|
||||
<td>@context.Protocol</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Headers</th>
|
||||
<td id="headerTd">
|
||||
<table id="headerTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var header in context.Headers)
|
||||
{
|
||||
<tr>
|
||||
<td>@header.Key</td>
|
||||
<td>@string.Join(";", header.Value)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status Code</th>
|
||||
<td>@context.StatusCode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<td>@context.User.Identity.Name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Claims</th>
|
||||
<td>
|
||||
@if (context.User.Claims.Any())
|
||||
{
|
||||
<table id="claimsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Issuer</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var claim in context.User.Claims)
|
||||
{
|
||||
<tr>
|
||||
<td>@claim.Issuer</td>
|
||||
<td>@claim.Value</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Scheme</th>
|
||||
<td>@context.Scheme</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Query</th>
|
||||
<td>@context.Query.Value</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Cookies</th>
|
||||
<td>
|
||||
@if (context.Cookies.Any())
|
||||
{
|
||||
<table id="cookieTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var cookie in context.Cookies)
|
||||
{
|
||||
<tr>
|
||||
<td>@cookie.Key</td>
|
||||
<td>@string.Join(";", cookie.Value)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
}
|
||||
<h2>Logs</h2>
|
||||
<form method="get">
|
||||
<select name="level">
|
||||
@foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
<option value="@severityInt" selected="selected">@severity</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@severityInt">@severity</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<input type="text" name="name" value="@Model.Options.NamePrefix" />
|
||||
<input type="submit" value="filter" />
|
||||
</form>
|
||||
<table id="logs">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
<th>Severity</th>
|
||||
<th>Name</th>
|
||||
<th>State</th>
|
||||
<th>Error</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@Traverse(Model.Activity.Root)
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$("#requestHeader").click(function () {
|
||||
$("#requestDetails").toggle();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
body {
|
||||
font-size: 0.9em;
|
||||
width: 90%;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0px;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid black;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
th {
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#headerTable, #cookieTable {
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#headerTd {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
#label {
|
||||
width: 20%;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
#logs{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#logs>tbody>tr>td {
|
||||
border-right: 1px dashed lightgray;
|
||||
}
|
||||
|
||||
#logs>thead>tr>th {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm.RazorViews
|
||||
{
|
||||
public class DetailsPageModel
|
||||
{
|
||||
public ActivityContext Activity { get; set; }
|
||||
|
||||
public ViewOptions Options { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,651 +0,0 @@
|
|||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm.RazorViews
|
||||
{
|
||||
#line hidden
|
||||
#line 1 "LogPage.cshtml"
|
||||
using System;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
using System.Threading.Tasks;
|
||||
#line 2 "LogPage.cshtml"
|
||||
using System.Collections.Generic;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 3 "LogPage.cshtml"
|
||||
using System.Globalization;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 4 "LogPage.cshtml"
|
||||
using System.Linq;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 5 "LogPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 6 "LogPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm.RazorViews;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 7 "LogPage.cshtml"
|
||||
using Microsoft.Extensions.RazorViews;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 8 "LogPage.cshtml"
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
internal class LogPage : Microsoft.Extensions.RazorViews.BaseView
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
public async override global::System.Threading.Tasks.Task ExecuteAsync()
|
||||
{
|
||||
WriteLiteral("\r\n");
|
||||
#line 118 "LogPage.cshtml"
|
||||
|
||||
Response.ContentType = "text/html; charset=utf-8";
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=""utf-8"" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src=""//ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js""></script>
|
||||
<style>
|
||||
body {
|
||||
font-size: .813em;
|
||||
white-space: nowrap;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
col:nth-child(2n) {
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0px auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
thead {
|
||||
font-size: 1em;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
tr {
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
#requestHeader {
|
||||
border-bottom: solid 1px gray;
|
||||
border-top: solid 1px gray;
|
||||
margin-bottom: 2px;
|
||||
font-size: 1em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
color: black;
|
||||
float: right;
|
||||
font-weight: normal;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.date, .time {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.logHeader {
|
||||
border-bottom: 1px ");
|
||||
WriteLiteral(@"solid lightgray;
|
||||
color: gray;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.logState {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.logTd {
|
||||
border-left: 1px solid gray;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.logs {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.logRow:hover {
|
||||
background-color: #D6F5FF;
|
||||
}
|
||||
|
||||
.requestRow>td {
|
||||
border-bottom: solid 1px gray;
|
||||
}
|
||||
|
||||
.severity {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.summary {
|
||||
color: black;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
.summary>th {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tab {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
#viewOptions {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
#viewOptions > * {
|
||||
margin: 5px;
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Arial, Helvtica, sans-serif;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Segoe UI', Helvetica, sans-serif;
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.critical {
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
");
|
||||
WriteLiteral("\r\n.information {\r\n color: blue;\r\n}\r\n\r\n.debug {\r\n color: black;\r\n}\r\n\r\n.warning {\r\n color: orange;\r\n}\r\n </style>\r\n</head>\r\n<body>\r\n <h1>ASP.NET Core Logs</h1>\r\n <form id=\"viewOptions\" method=\"get\">\r\n <select name=\"level\">\r\n");
|
||||
#line 284 "LogPage.cshtml"
|
||||
foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 6741, "\"", 6761, 1);
|
||||
#line 289 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6749, severityInt, 6749, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(" selected=\"selected\">");
|
||||
#line 289 "LogPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 290 "LogPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 6890, "\"", 6910, 1);
|
||||
#line 293 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6898, severityInt, 6898, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 293 "LogPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 294 "LogPage.cshtml"
|
||||
}
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </select>\r\n <input type=\"text\" name=\"name\"");
|
||||
BeginWriteAttribute("value", " value=\"", 7023, "\"", 7056, 1);
|
||||
#line 297 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 7031, Model.Options.NamePrefix, 7031, 25, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(@" />
|
||||
<input type=""submit"" value=""filter"" />
|
||||
</form>
|
||||
<form id=""clear"" method=""post"" action="""">
|
||||
<button type=""submit"" name=""clear"" value=""1"">Clear Logs</button>
|
||||
</form>
|
||||
|
||||
<table id=""requestTable"">
|
||||
<thead id=""requestHeader"">
|
||||
<tr>
|
||||
<th class=""path"">Path</th>
|
||||
<th class=""method"">Method</th>
|
||||
<th class=""host"">Host</th>
|
||||
<th class=""statusCode"">Status Code</th>
|
||||
<th class=""logs"">Logs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<colgroup>
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
</colgroup>
|
||||
");
|
||||
#line 321 "LogPage.cshtml"
|
||||
foreach (var activity in Model.Activities.Reverse())
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <tbody>\r\n <tr class=\"requestRow\">\r\n");
|
||||
#line 325 "LogPage.cshtml"
|
||||
|
||||
var activityPath = Model.Path.Value + "/" + activity.Id;
|
||||
if (activity.HttpInfo != null)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" \t<td><a");
|
||||
BeginWriteAttribute("href", " href=\"", 8120, "\"", 8140, 1);
|
||||
#line 329 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 8127, activityPath, 8127, 13, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
BeginWriteAttribute("title", " title=\"", 8141, "\"", 8172, 1);
|
||||
#line 329 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 8149, activity.HttpInfo.Path, 8149, 23, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 329 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.Path);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</a></td>\r\n <td>");
|
||||
#line 330 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.Method);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 331 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.Host);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 332 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.StatusCode);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n");
|
||||
#line 333 "LogPage.cshtml"
|
||||
}
|
||||
else if (activity.RepresentsScope)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <td colspan=\"4\"><a");
|
||||
BeginWriteAttribute("href", " href=\"", 8562, "\"", 8582, 1);
|
||||
#line 336 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 8569, activityPath, 8569, 13, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
BeginWriteAttribute("title", " title=\"", 8583, "\"", 8611, 1);
|
||||
#line 336 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 8591, activity.Root.State, 8591, 20, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 336 "LogPage.cshtml"
|
||||
Write(activity.Root.State);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</a></td>\r\n");
|
||||
#line 337 "LogPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <td colspan=\"4\"><a");
|
||||
BeginWriteAttribute("href", " href=\"", 8774, "\"", 8794, 1);
|
||||
#line 340 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 8781, activityPath, 8781, 13, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">Non-scope Log</a></td>\r\n");
|
||||
#line 341 "LogPage.cshtml"
|
||||
}
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@" <td class=""logTd"">
|
||||
<table class=""logTable"">
|
||||
<thead class=""logHeader"">
|
||||
<tr class=""headerRow"">
|
||||
<th class=""date"">Date</th>
|
||||
<th class=""time"">Time</th>
|
||||
<th class=""name"">Name</th>
|
||||
<th class=""severity"">Severity</th>
|
||||
<th class=""state"">State</th>
|
||||
<th>Error<span class=""collapse"">^</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
");
|
||||
#line 355 "LogPage.cshtml"
|
||||
|
||||
var counts = new Dictionary<string, int>();
|
||||
counts["Critical"] = 0;
|
||||
counts["Error"] = 0;
|
||||
counts["Warning"] = 0;
|
||||
counts["Information"] = 0;
|
||||
counts["Debug"] = 0;
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <tbody class=\"logBody\">\r\n");
|
||||
#line 364 "LogPage.cshtml"
|
||||
if (!activity.RepresentsScope)
|
||||
{
|
||||
// message not within a scope
|
||||
var logInfo = activity.Root.Messages.FirstOrDefault();
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 368 "LogPage.cshtml"
|
||||
Write(LogRow(logInfo, 0));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 368 "LogPage.cshtml"
|
||||
|
||||
counts[logInfo.Severity.ToString()] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 373 "LogPage.cshtml"
|
||||
Write(Traverse(activity.Root, 0, counts));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 373 "LogPage.cshtml"
|
||||
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </tbody>\r\n <tbody class=\"summary\">\r\n <tr class=\"logRow\">\r\n <td>");
|
||||
#line 378 "LogPage.cshtml"
|
||||
Write(activity.Time.ToString("MM-dd-yyyy HH:mm:ss"));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n");
|
||||
#line 379 "LogPage.cshtml"
|
||||
foreach (var kvp in counts)
|
||||
{
|
||||
if (string.Equals("Debug", kvp.Key)) {
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <td>");
|
||||
#line 382 "LogPage.cshtml"
|
||||
Write(kvp.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" ");
|
||||
#line 382 "LogPage.cshtml"
|
||||
Write(kvp.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("<span class=\"collapse\">v</span></td>\r\n");
|
||||
#line 383 "LogPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" <td>");
|
||||
#line 386 "LogPage.cshtml"
|
||||
Write(kvp.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" ");
|
||||
#line 386 "LogPage.cshtml"
|
||||
Write(kvp.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n");
|
||||
#line 387 "LogPage.cshtml"
|
||||
}
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" </tr>\r\n </tbody>\r\n </table>\r\n </td>\r\n </tr>\r\n </tbody>\r\n");
|
||||
#line 395 "LogPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@" </table>
|
||||
<script type=""text/javascript"">
|
||||
$(document).ready(function () {
|
||||
$("".logBody"").hide();
|
||||
$("".logTable > thead"").hide();
|
||||
$("".logTable > thead"").click(function () {
|
||||
$(this).closest("".logTable"").find(""tbody"").hide();
|
||||
$(this).closest("".logTable"").find("".summary"").show();
|
||||
$(this).hide();
|
||||
});
|
||||
$("".logTable > .summary"").click(function () {
|
||||
$(this).closest("".logTable"").find(""tbody"").show();
|
||||
$(this).closest("".logTable"").find(""thead"").show();
|
||||
$(this).hide();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
#line 11 "LogPage.cshtml"
|
||||
|
||||
public LogPage(LogPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public LogPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log, int level)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
PushWriter(writer);
|
||||
WriteLiteral(" <tr class=\"logRow\">\r\n <td>");
|
||||
Write(string.Format("{0:MM/dd/yy}", log.Time));
|
||||
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
Write(string.Format("{0:H:mm:ss}", log.Time));
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Name}\">");
|
||||
Write(log.Name);
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteral($"</td>\r\n <td class=\"{severity}\">");
|
||||
Write(log.Severity);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Message}\"> \r\n");
|
||||
|
||||
for (var i = 0; i < level; i++)
|
||||
{
|
||||
WriteLiteral(" <span class=\"tab\"></span>\r\n");
|
||||
}
|
||||
|
||||
WriteLiteral(" ");
|
||||
Write(log.Message);
|
||||
|
||||
WriteLiteral($"\r\n </td>\r\n <td title=\"{log.Exception}\">");
|
||||
|
||||
Write(log.Exception);
|
||||
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
PopWriter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node, int level, Dictionary<string, int> counts)
|
||||
{
|
||||
return new HelperResult((writer) => {
|
||||
PushWriter(writer);
|
||||
|
||||
// print start of scope
|
||||
Write(LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.StartTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = "Beginning " + node.State,
|
||||
}, level));
|
||||
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
Write(LogRow(node.Messages[messageIndex], level));
|
||||
|
||||
counts[node.Messages[messageIndex].Severity.ToString()]++;
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(Traverse(node.Children[childIndex], level + 1, counts));
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
Write(LogRow(node.Messages[i], level));
|
||||
counts[node.Messages[i].Severity.ToString()]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
Write(Traverse(node.Children[i], level + 1, counts));
|
||||
}
|
||||
}
|
||||
// print end of scope
|
||||
Write(LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.EndTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = string.Format("Completed {0} in {1}ms", node.State, node.EndTime - node.StartTime)
|
||||
}, level));
|
||||
|
||||
PopWriter();
|
||||
});
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
|
|
@ -1,267 +0,0 @@
|
|||
@using System
|
||||
@using System.Collections.Generic
|
||||
@using System.Globalization
|
||||
@using System.Linq
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm.RazorViews
|
||||
@using Microsoft.Extensions.RazorViews
|
||||
@using Microsoft.Extensions.Logging
|
||||
|
||||
@functions
|
||||
{
|
||||
public LogPage(LogPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public LogPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log, int level)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
PushWriter(writer);
|
||||
WriteLiteral(" <tr class=\"logRow\">\r\n <td>");
|
||||
Write(string.Format("{0:MM/dd/yy}", log.Time));
|
||||
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
Write(string.Format("{0:H:mm:ss}", log.Time));
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Name}\">");
|
||||
Write(log.Name);
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteral($"</td>\r\n <td class=\"{severity}\">");
|
||||
Write(log.Severity);
|
||||
|
||||
WriteLiteral($"</td>\r\n <td title=\"{log.Message}\"> \r\n");
|
||||
|
||||
for (var i = 0; i < level; i++)
|
||||
{
|
||||
WriteLiteral(" <span class=\"tab\"></span>\r\n");
|
||||
}
|
||||
|
||||
WriteLiteral(" ");
|
||||
Write(log.Message);
|
||||
|
||||
WriteLiteral($"\r\n </td>\r\n <td title=\"{log.Exception}\">");
|
||||
|
||||
Write(log.Exception);
|
||||
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
PopWriter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node, int level, Dictionary<string, int> counts)
|
||||
{
|
||||
return new HelperResult((writer) => {
|
||||
PushWriter(writer);
|
||||
|
||||
// print start of scope
|
||||
Write(LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.StartTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = "Beginning " + node.State,
|
||||
}, level));
|
||||
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
Write(LogRow(node.Messages[messageIndex], level));
|
||||
|
||||
counts[node.Messages[messageIndex].Severity.ToString()]++;
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(Traverse(node.Children[childIndex], level + 1, counts));
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
Write(LogRow(node.Messages[i], level));
|
||||
counts[node.Messages[i].Severity.ToString()]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
Write(Traverse(node.Children[i], level + 1, counts));
|
||||
}
|
||||
}
|
||||
// print end of scope
|
||||
Write(LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.EndTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = string.Format("Completed {0} in {1}ms", node.State, node.EndTime - node.StartTime)
|
||||
}, level));
|
||||
|
||||
PopWriter();
|
||||
});
|
||||
}
|
||||
}
|
||||
@{
|
||||
Response.ContentType = "text/html; charset=utf-8";
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js"></script>
|
||||
<style>
|
||||
<%$ include: LogPage.css %>
|
||||
<%$ include: Shared.css %>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
<form id="viewOptions" method="get">
|
||||
<select name="level">
|
||||
@foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
<option value="@severityInt" selected="selected">@severity</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@severityInt">@severity</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<input type="text" name="name" value="@Model.Options.NamePrefix" />
|
||||
<input type="submit" value="filter" />
|
||||
</form>
|
||||
<form id="clear" method="post" action="">
|
||||
<button type="submit" name="clear" value="1">Clear Logs</button>
|
||||
</form>
|
||||
|
||||
<table id="requestTable">
|
||||
<thead id="requestHeader">
|
||||
<tr>
|
||||
<th class="path">Path</th>
|
||||
<th class="method">Method</th>
|
||||
<th class="host">Host</th>
|
||||
<th class="statusCode">Status Code</th>
|
||||
<th class="logs">Logs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<colgroup>
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
</colgroup>
|
||||
@foreach (var activity in Model.Activities.Reverse())
|
||||
{
|
||||
<tbody>
|
||||
<tr class="requestRow">
|
||||
@{
|
||||
var activityPath = Model.Path.Value + "/" + activity.Id;
|
||||
if (activity.HttpInfo != null)
|
||||
{
|
||||
<td><a href="@activityPath" title="@activity.HttpInfo.Path">@activity.HttpInfo.Path</a></td>
|
||||
<td>@activity.HttpInfo.Method</td>
|
||||
<td>@activity.HttpInfo.Host</td>
|
||||
<td>@activity.HttpInfo.StatusCode</td>
|
||||
}
|
||||
else if (activity.RepresentsScope)
|
||||
{
|
||||
<td colspan="4"><a href="@activityPath" title="@activity.Root.State">@activity.Root.State</a></td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td colspan="4"><a href="@activityPath">Non-scope Log</a></td>
|
||||
}
|
||||
}
|
||||
<td class="logTd">
|
||||
<table class="logTable">
|
||||
<thead class="logHeader">
|
||||
<tr class="headerRow">
|
||||
<th class="date">Date</th>
|
||||
<th class="time">Time</th>
|
||||
<th class="name">Name</th>
|
||||
<th class="severity">Severity</th>
|
||||
<th class="state">State</th>
|
||||
<th>Error<span class="collapse">^</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@{
|
||||
var counts = new Dictionary<string, int>();
|
||||
counts["Critical"] = 0;
|
||||
counts["Error"] = 0;
|
||||
counts["Warning"] = 0;
|
||||
counts["Information"] = 0;
|
||||
counts["Debug"] = 0;
|
||||
}
|
||||
<tbody class="logBody">
|
||||
@if (!activity.RepresentsScope)
|
||||
{
|
||||
// message not within a scope
|
||||
var logInfo = activity.Root.Messages.FirstOrDefault();
|
||||
@LogRow(logInfo, 0)
|
||||
counts[logInfo.Severity.ToString()] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@Traverse(activity.Root, 0, counts)
|
||||
}
|
||||
</tbody>
|
||||
<tbody class="summary">
|
||||
<tr class="logRow">
|
||||
<td>@activity.Time.ToString("MM-dd-yyyy HH:mm:ss")</td>
|
||||
@foreach (var kvp in counts)
|
||||
{
|
||||
if (string.Equals("Debug", kvp.Key)) {
|
||||
<td>@kvp.Value @kvp.Key<span class="collapse">v</span></td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td>@kvp.Value @kvp.Key</td>
|
||||
}
|
||||
}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
}
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$(".logBody").hide();
|
||||
$(".logTable > thead").hide();
|
||||
$(".logTable > thead").click(function () {
|
||||
$(this).closest(".logTable").find("tbody").hide();
|
||||
$(this).closest(".logTable").find(".summary").show();
|
||||
$(this).hide();
|
||||
});
|
||||
$(".logTable > .summary").click(function () {
|
||||
$(this).closest(".logTable").find("tbody").show();
|
||||
$(this).closest(".logTable").find("thead").show();
|
||||
$(this).hide();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
body {
|
||||
font-size: .813em;
|
||||
white-space: nowrap;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
col:nth-child(2n) {
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0px auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
thead {
|
||||
font-size: 1em;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
tr {
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
#requestHeader {
|
||||
border-bottom: solid 1px gray;
|
||||
border-top: solid 1px gray;
|
||||
margin-bottom: 2px;
|
||||
font-size: 1em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
color: black;
|
||||
float: right;
|
||||
font-weight: normal;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.date, .time {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.logHeader {
|
||||
border-bottom: 1px solid lightgray;
|
||||
color: gray;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.logState {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.logTd {
|
||||
border-left: 1px solid gray;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.logs {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.logRow:hover {
|
||||
background-color: #D6F5FF;
|
||||
}
|
||||
|
||||
.requestRow>td {
|
||||
border-bottom: solid 1px gray;
|
||||
}
|
||||
|
||||
.severity {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.summary {
|
||||
color: black;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
.summary>th {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tab {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
#viewOptions {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
#viewOptions > * {
|
||||
margin: 5px;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm.RazorViews
|
||||
{
|
||||
public class LogPageModel
|
||||
{
|
||||
public IEnumerable<ActivityContext> Activities { get; set; }
|
||||
|
||||
public ViewOptions Options { get; set; }
|
||||
|
||||
public PathString Path { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,512 +0,0 @@
|
|||
namespace Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
{
|
||||
#line 1 "DetailsPage.cshtml"
|
||||
using System
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 2 "DetailsPage.cshtml"
|
||||
using System.Globalization
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 3 "DetailsPage.cshtml"
|
||||
using System.Linq
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 4 "DetailsPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 5 "DetailsPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 6 "DetailsPage.cshtml"
|
||||
using Microsoft.AspNetCore.DiagnosticsViewPage.Views
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 7 "DetailsPage.cshtml"
|
||||
using Microsoft.Extensions.Logging
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
using System.Threading.Tasks;
|
||||
[Obsolete("This type is for internal use only and will be removed in a future version.")]
|
||||
public class DetailsPage : Microsoft.AspNetCore.DiagnosticsViewPage.Views.BaseView
|
||||
{
|
||||
#line 10 "DetailsPage.cshtml"
|
||||
|
||||
public DetailsPage(DetailsPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DetailsPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
WriteLiteralTo(writer, " <tr>\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:MM/dd/yy}", log.Time));
|
||||
WriteLiteralTo(writer, "</td>\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:H:mm:ss}", log.Time));
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td class=\"{severity}\">");
|
||||
WriteTo(writer, log.Severity);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Name}\">");
|
||||
WriteTo(writer, log.Name);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Message}\""+
|
||||
"class=\"logState\" width=\"100px\">");
|
||||
WriteTo(writer, log.Message);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Exception}\">");
|
||||
WriteTo(writer, log.Exception);
|
||||
|
||||
WriteLiteralTo(writer, "</td>\r\n </tr>\r\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
LogRow(node.Messages[messageIndex]);
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Traverse(node.Children[childIndex]);
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
LogRow(node.Messages[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
Traverse(node.Children[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line hidden
|
||||
public DetailsPage()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
WriteLiteral("\r\n");
|
||||
#line 84 "DetailsPage.cshtml"
|
||||
|
||||
Response.ContentType = "text/html";
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(@"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=""utf-8"" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src=""http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js""></script>
|
||||
<style>
|
||||
<%$ include: Shared.css % > <%$ include: DetailsPage.css % >
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
");
|
||||
#line 99 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 99 "DetailsPage.cshtml"
|
||||
|
||||
var context = Model.Activity?.HttpInfo;
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" ");
|
||||
#line 102 "DetailsPage.cshtml"
|
||||
if (context != null)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <h2 id=\"requestHeader\">Request Details</h2>\r\n <table id=\"requestDetails\">\r\n <colgroup><col id=\"label\" /><col /></colgroup>\r\n\r\n <tr>\r\n <th>Path</th>\r\n <td>");
|
||||
#line 110 "DetailsPage.cshtml"
|
||||
Write(context.Path);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Host</th>\r\n <td>");
|
||||
#line 114 "DetailsPage.cshtml"
|
||||
Write(context.Host);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Content Type</th>\r\n <td>");
|
||||
#line 118 "DetailsPage.cshtml"
|
||||
Write(context.ContentType);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Method</th>\r\n <td>");
|
||||
#line 122 "DetailsPage.cshtml"
|
||||
Write(context.Method);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Protocol</th>\r\n <td>");
|
||||
#line 126 "DetailsPage.cshtml"
|
||||
Write(context.Protocol);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Headers</th>
|
||||
<td id=""headerTd"">
|
||||
<table id=""headerTable"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
");
|
||||
#line 139 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 139 "DetailsPage.cshtml"
|
||||
foreach (var header in context.Headers)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
#line 142 "DetailsPage.cshtml"
|
||||
Write(header.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 143 "DetailsPage.cshtml"
|
||||
Write(string.Join(";", header.Value));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
#line 145 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </tbody>\r\n </table>\r\n </td>\r\n </tr>\r\n <tr>\r\n <th>Status Code</th>\r\n <td>");
|
||||
#line 152 "DetailsPage.cshtml"
|
||||
Write(context.StatusCode);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>User</th>\r\n <td>");
|
||||
#line 156 "DetailsPage.cshtml"
|
||||
Write(context.User.Identity.Name);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Claims</th>\r\n <td>\r\n");
|
||||
#line 161 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 161 "DetailsPage.cshtml"
|
||||
if (context.User.Claims.Any())
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(@" <table id=""claimsTable"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Issuer</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
");
|
||||
#line 171 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 171 "DetailsPage.cshtml"
|
||||
foreach (var claim in context.User.Claims)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
#line 174 "DetailsPage.cshtml"
|
||||
Write(claim.Issuer);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 175 "DetailsPage.cshtml"
|
||||
Write(claim.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
#line 177 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </tbody>\r\n </table>\r\n");
|
||||
#line 180 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </td>\r\n </tr>\r\n <tr>\r\n <th>Scheme</th>\r\n <td>");
|
||||
#line 185 "DetailsPage.cshtml"
|
||||
Write(context.Scheme);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Query</th>\r\n <td>");
|
||||
#line 189 "DetailsPage.cshtml"
|
||||
Write(context.Query.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n <tr>\r\n <th>Cookies</th>\r\n <td>\r\n");
|
||||
#line 194 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 194 "DetailsPage.cshtml"
|
||||
if (context.Cookies.Any())
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(@" <table id=""cookieTable"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
");
|
||||
#line 204 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 204 "DetailsPage.cshtml"
|
||||
foreach (var cookie in context.Cookies)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <tr>\r\n <td>");
|
||||
#line 207 "DetailsPage.cshtml"
|
||||
Write(cookie.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 208 "DetailsPage.cshtml"
|
||||
Write(string.Join(";", cookie.Value));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n </tr>\r\n");
|
||||
#line 210 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </tbody>\r\n </table>\r\n");
|
||||
#line 213 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </td>\r\n </tr>\r\n </table>\r\n");
|
||||
#line 217 "DetailsPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <h2>Logs</h2>\r\n <form method=\"get\">\r\n <select name=\"level\">\r\n");
|
||||
#line 221 "DetailsPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 221 "DetailsPage.cshtml"
|
||||
foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 7723, "\"", 7743, 1);
|
||||
#line 226 "DetailsPage.cshtml"
|
||||
WriteAttributeValue("", 7731, severityInt, 7731, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(" selected=\"selected\">");
|
||||
#line 226 "DetailsPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 227 "DetailsPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 7872, "\"", 7892, 1);
|
||||
#line 230 "DetailsPage.cshtml"
|
||||
WriteAttributeValue("", 7880, severityInt, 7880, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 230 "DetailsPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 231 "DetailsPage.cshtml"
|
||||
}
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </select>\r\n <input type=\"text\" name=\"name\"");
|
||||
BeginWriteAttribute("value", " value=\"", 8005, "\"", 8038, 1);
|
||||
#line 234 "DetailsPage.cshtml"
|
||||
WriteAttributeValue("", 8013, Model.Options.NamePrefix, 8013, 25, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(@" />
|
||||
<input type=""submit"" value=""filter"" />
|
||||
</form>
|
||||
<table id=""logs"">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
<th>Severity</th>
|
||||
<th>Name</th>
|
||||
<th>State</th>
|
||||
<th>Error</th>
|
||||
</tr>
|
||||
</thead>
|
||||
");
|
||||
#line 248 "DetailsPage.cshtml"
|
||||
Write(Traverse(Model.Activity.Root));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(@"
|
||||
</table>
|
||||
<script type=""text/javascript"">
|
||||
$(document).ready(function () {
|
||||
$(""#requestHeader"").click(function () {
|
||||
$(""#requestDetails"").toggle();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
@using System
|
||||
@using System.Globalization
|
||||
@using System.Linq
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
@using Microsoft.AspNetCore.DiagnosticsViewPage.Views
|
||||
@using Microsoft.Extensions.Logging
|
||||
|
||||
@functions
|
||||
{
|
||||
public DetailsPage(DetailsPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DetailsPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
WriteLiteralTo(writer, " <tr>\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:MM/dd/yy}", log.Time));
|
||||
WriteLiteralTo(writer, "</td>\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:H:mm:ss}", log.Time));
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td class=\"{severity}\">");
|
||||
WriteTo(writer, log.Severity);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Name}\">");
|
||||
WriteTo(writer, log.Name);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Message}\""+
|
||||
"class=\"logState\" width=\"100px\">");
|
||||
WriteTo(writer, log.Message);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Exception}\">");
|
||||
WriteTo(writer, log.Exception);
|
||||
|
||||
WriteLiteralTo(writer, "</td>\r\n </tr>\r\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
LogRow(node.Messages[messageIndex]);
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Traverse(node.Children[childIndex]);
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
LogRow(node.Messages[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
Traverse(node.Children[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@{
|
||||
Response.ContentType = "text/html";
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js"></script>
|
||||
<style>
|
||||
<%$ include: Shared.css % > <%$ include: DetailsPage.css % >
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
@{
|
||||
var context = Model.Activity?.HttpInfo;
|
||||
}
|
||||
@if (context != null)
|
||||
{
|
||||
<h2 id="requestHeader">Request Details</h2>
|
||||
<table id="requestDetails">
|
||||
<colgroup><col id="label" /><col /></colgroup>
|
||||
|
||||
<tr>
|
||||
<th>Path</th>
|
||||
<td>@context.Path</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Host</th>
|
||||
<td>@context.Host</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Content Type</th>
|
||||
<td>@context.ContentType</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Method</th>
|
||||
<td>@context.Method</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Protocol</th>
|
||||
<td>@context.Protocol</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Headers</th>
|
||||
<td id="headerTd">
|
||||
<table id="headerTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var header in context.Headers)
|
||||
{
|
||||
<tr>
|
||||
<td>@header.Key</td>
|
||||
<td>@string.Join(";", header.Value)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status Code</th>
|
||||
<td>@context.StatusCode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<td>@context.User.Identity.Name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Claims</th>
|
||||
<td>
|
||||
@if (context.User.Claims.Any())
|
||||
{
|
||||
<table id="claimsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Issuer</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var claim in context.User.Claims)
|
||||
{
|
||||
<tr>
|
||||
<td>@claim.Issuer</td>
|
||||
<td>@claim.Value</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Scheme</th>
|
||||
<td>@context.Scheme</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Query</th>
|
||||
<td>@context.Query.Value</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Cookies</th>
|
||||
<td>
|
||||
@if (context.Cookies.Any())
|
||||
{
|
||||
<table id="cookieTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Variable</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var cookie in context.Cookies)
|
||||
{
|
||||
<tr>
|
||||
<td>@cookie.Key</td>
|
||||
<td>@string.Join(";", cookie.Value)</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
}
|
||||
<h2>Logs</h2>
|
||||
<form method="get">
|
||||
<select name="level">
|
||||
@foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
<option value="@severityInt" selected="selected">@severity</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@severityInt">@severity</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<input type="text" name="name" value="@Model.Options.NamePrefix" />
|
||||
<input type="submit" value="filter" />
|
||||
</form>
|
||||
<table id="logs">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Time</th>
|
||||
<th>Severity</th>
|
||||
<th>Name</th>
|
||||
<th>State</th>
|
||||
<th>Error</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@Traverse(Model.Activity.Root)
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$("#requestHeader").click(function () {
|
||||
$("#requestDetails").toggle();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
body {
|
||||
font-size: 0.9em;
|
||||
width: 90%;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0px;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid black;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
th {
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#headerTable, #cookieTable {
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#headerTd {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
#label {
|
||||
width: 20%;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
#logs{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#logs>tbody>tr>td {
|
||||
border-right: 1px dashed lightgray;
|
||||
}
|
||||
|
||||
#logs>thead>tr>th {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
{
|
||||
[Obsolete("This type is for internal use only and will be removed in a future version.")]
|
||||
public class DetailsPageModel
|
||||
{
|
||||
public ActivityContext Activity { get; set; }
|
||||
|
||||
public ViewOptions Options { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,579 +0,0 @@
|
|||
namespace Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
{
|
||||
#line 1 "LogPage.cshtml"
|
||||
using System
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 2 "LogPage.cshtml"
|
||||
using System.Collections.Generic
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 3 "LogPage.cshtml"
|
||||
using System.Globalization
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 4 "LogPage.cshtml"
|
||||
using System.Linq
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 5 "LogPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 6 "LogPage.cshtml"
|
||||
using Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 7 "LogPage.cshtml"
|
||||
using Microsoft.AspNetCore.DiagnosticsViewPage.Views
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
#line 8 "LogPage.cshtml"
|
||||
using Microsoft.Extensions.Logging
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
;
|
||||
using System.Threading.Tasks;
|
||||
[Obsolete("This type is for internal use only and will be removed in a future version.")]
|
||||
public class LogPage : Microsoft.AspNetCore.DiagnosticsViewPage.Views.BaseView
|
||||
{
|
||||
#line 11 "LogPage.cshtml"
|
||||
|
||||
public LogPage(LogPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public LogPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log, int level)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
|
||||
WriteLiteralTo(writer, " <tr class=\"logRow\">\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:MM/dd/yy}", log.Time));
|
||||
|
||||
WriteLiteralTo(writer, "</td>\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:H:mm:ss}", log.Time));
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Name}\">");
|
||||
WriteTo(writer, log.Name);
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td class=\"{severity}\">");
|
||||
WriteTo(writer, log.Severity);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Message}\"> \r\n");
|
||||
|
||||
for (var i = 0; i < level; i++)
|
||||
{
|
||||
WriteLiteralTo(writer, " <span class=\"tab\"></span>\r\n");
|
||||
}
|
||||
|
||||
WriteLiteralTo(writer, " ");
|
||||
WriteTo(writer, log.Message);
|
||||
|
||||
WriteLiteralTo(writer, $"\r\n </td>\r\n <td title=\"{log.Exception}\">");
|
||||
|
||||
WriteTo(writer, log.Exception);
|
||||
|
||||
WriteLiteralTo(writer, "</td>\r\n </tr>\r\n");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node, int level, Dictionary<string, int> counts)
|
||||
{
|
||||
return new HelperResult((writer) => {
|
||||
// print start of scope
|
||||
WriteTo(writer, LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.StartTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = "Beginning " + node.State,
|
||||
}, level));
|
||||
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
WriteTo(writer, LogRow(node.Messages[messageIndex], level));
|
||||
|
||||
counts[node.Messages[messageIndex].Severity.ToString()]++;
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTo(writer, Traverse(node.Children[childIndex], level + 1, counts));
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
WriteTo(writer, LogRow(node.Messages[i], level));
|
||||
counts[node.Messages[i].Severity.ToString()]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
WriteTo(writer, Traverse(node.Children[i], level + 1, counts));
|
||||
}
|
||||
}
|
||||
// print end of scope
|
||||
WriteTo(writer, LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.EndTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = string.Format("Completed {0} in {1}ms", node.State, node.EndTime - node.StartTime)
|
||||
}, level));
|
||||
});
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line hidden
|
||||
public LogPage()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable 1998
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
WriteLiteral("\r\n");
|
||||
#line 114 "LogPage.cshtml"
|
||||
|
||||
Response.ContentType = "text/html";
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(@"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=""utf-8"" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src=""//ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js""></script>
|
||||
<style>
|
||||
body {\r\n font-size: .813em;\r\n white-space: nowrap;\r\n margin: 20px;\r\n}\r\n\r\ncol:nth-child(2n) {\r\n background-color: #FAFAFA;\r\n}\r\n\r\nform { \r\n display: inline-block; \r\n}\r\n\r\nh1 {\r\n margin-left: 25px;\r\n}\r\n\r\ntable {\r\n margin: 0px auto;\r\n border-collapse: collapse;\r\n border-spacing: 0px;\r\n table-layout: fixed;\r\n width: 100%;\r\n}\r\n\r\ntd, th {\r\n padding: 4px;\r\n}\r\n\r\nthead {\r\n font-size: 1em;\r\n font-family: Arial;\r\n}\r\n\r\ntr {\r\n height: 23px;\r\n}\r\n\r\n#requestHeader {\r\n border-bottom: solid 1px gray;\r\n border-top: solid 1px gray;\r\n margin-bottom: 2px;\r\n font-size: 1em;\r\n line-height: 2em;\r\n}\r\n\r\n.collapse {\r\n color: black;\r\n float: right;\r\n font-weight: normal;\r\n width: 1em;\r\n}\r\n\r\n.date, .time {\r\n width: 70px; \r\n}\r\n\r\n.logHeader {\r\n border-bottom: 1px solid lightgray;\r\n color: gray;\r\n text-align: left;\r\n}\r\n\r\n.logState {\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n}\r\n\r\n.logTd {\r\n border-left: 1px solid gray;\r\n padding: 0px;\r\n}\r\n\r\n.logs {\r\n width: 80%;\r\n}\r\n\r\n.logRow:hover {\r\n background-color: #D6F5FF;\r\n}\r\n\r\n.requestRow>td {\r\n border-bottom: solid 1px gray;\r\n}\r\n\r\n.severity {\r\n width: 80px;\r\n}\r\n\r\n.summary {\r\n color: black;\r\n line-height: 1.8em;\r\n}\r\n\r\n.summary>th {\r\n font-weight: normal;\r\n}\r\n\r\n.tab {\r\n margin-left: 30px;\r\n}\r\n\r\n#viewOptions {\r\n margin: 20px;\r\n}\r\n\r\n#viewOptions > * {\r\n margin: 5px;\r\n}
|
||||
body {\r\n font-family: 'Segoe UI', Tahoma, Arial, Helvtica, sans-serif;\r\n line-height: 1.4em;\r\n}\r\n\r\nh1 {\r\n font-family: 'Segoe UI', Helvetica, sans-serif;\r\n font-size: 2.5em;\r\n}\r\n\r\ntd {\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n}\r\n\r\ntr:nth-child(2n) {\r\n background-color: #F6F6F6;\r\n}\r\n\r\n.critical {\r\n background-color: red;\r\n color: white;\r\n}\r\n\r\n.error {\r\n color: red;\r\n}\r\n\r\n.information {\r\n color: blue;\r\n}\r\n\r\n.debug {\r\n color: black;\r\n}\r\n\r\n.warning {\r\n color: orange;\r\n}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
<form id=""viewOptions"" method=""get"">
|
||||
<select name=""level"">
|
||||
");
|
||||
#line 133 "LogPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 133 "LogPage.cshtml"
|
||||
foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 4934, "\"", 4954, 1);
|
||||
#line 138 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 4942, severityInt, 4942, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(" selected=\"selected\">");
|
||||
#line 138 "LogPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 139 "LogPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <option");
|
||||
BeginWriteAttribute("value", " value=\"", 5083, "\"", 5103, 1);
|
||||
#line 142 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 5091, severityInt, 5091, 12, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 142 "LogPage.cshtml"
|
||||
Write(severity);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</option>\r\n");
|
||||
#line 143 "LogPage.cshtml"
|
||||
}
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </select>\r\n <input type=\"text\" name=\"name\"");
|
||||
BeginWriteAttribute("value", " value=\"", 5216, "\"", 5249, 1);
|
||||
#line 146 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 5224, Model.Options.NamePrefix, 5224, 25, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(@" />
|
||||
<input type=""submit"" value=""filter"" />
|
||||
</form>
|
||||
<form id=""clear"" method=""post"" action="""">
|
||||
<button type=""submit"" name=""clear"" value=""1"">Clear Logs</button>
|
||||
</form>
|
||||
|
||||
<table id=""requestTable"">
|
||||
<thead id=""requestHeader"">
|
||||
<tr>
|
||||
<th class=""path"">Path</th>
|
||||
<th class=""method"">Method</th>
|
||||
<th class=""host"">Host</th>
|
||||
<th class=""statusCode"">Status Code</th>
|
||||
<th class=""logs"">Logs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<colgroup>
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
</colgroup>
|
||||
");
|
||||
#line 170 "LogPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 170 "LogPage.cshtml"
|
||||
foreach (var activity in Model.Activities.Reverse())
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <tbody>\r\n <tr class=\"requestRow\">\r\n");
|
||||
#line 174 "LogPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 174 "LogPage.cshtml"
|
||||
|
||||
var activityPath = Model.Path.Value + "/" + activity.Id;
|
||||
if (activity.HttpInfo != null)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" \t<td><a");
|
||||
BeginWriteAttribute("href", " href=\"", 6313, "\"", 6333, 1);
|
||||
#line 178 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6320, activityPath, 6320, 13, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
BeginWriteAttribute("title", " title=\"", 6334, "\"", 6365, 1);
|
||||
#line 178 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6342, activity.HttpInfo.Path, 6342, 23, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 178 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.Path);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</a></td>\r\n <td>");
|
||||
#line 179 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.Method);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 180 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.Host);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n <td>");
|
||||
#line 181 "LogPage.cshtml"
|
||||
Write(activity.HttpInfo.StatusCode);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n");
|
||||
#line 182 "LogPage.cshtml"
|
||||
}
|
||||
else if (activity.RepresentsScope)
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <td colspan=\"4\"><a");
|
||||
BeginWriteAttribute("href", " href=\"", 6755, "\"", 6775, 1);
|
||||
#line 185 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6762, activityPath, 6762, 13, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
BeginWriteAttribute("title", " title=\"", 6776, "\"", 6804, 1);
|
||||
#line 185 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6784, activity.Root.State, 6784, 20, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">");
|
||||
#line 185 "LogPage.cshtml"
|
||||
Write(activity.Root.State);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</a></td>\r\n");
|
||||
#line 186 "LogPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <td colspan=\"4\"><a");
|
||||
BeginWriteAttribute("href", " href=\"", 6967, "\"", 6987, 1);
|
||||
#line 189 "LogPage.cshtml"
|
||||
WriteAttributeValue("", 6974, activityPath, 6974, 13, false);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
EndWriteAttribute();
|
||||
WriteLiteral(">Non-scope Log</a></td>\r\n");
|
||||
#line 190 "LogPage.cshtml"
|
||||
}
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(@" <td class=""logTd"">
|
||||
<table class=""logTable"">
|
||||
<thead class=""logHeader"">
|
||||
<tr class=""headerRow"">
|
||||
<th class=""date"">Date</th>
|
||||
<th class=""time"">Time</th>
|
||||
<th class=""name"">Name</th>
|
||||
<th class=""severity"">Severity</th>
|
||||
<th class=""state"">State</th>
|
||||
<th>Error<span class=""collapse"">^</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
");
|
||||
#line 204 "LogPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 204 "LogPage.cshtml"
|
||||
|
||||
var counts = new Dictionary<string, int>();
|
||||
counts["Critical"] = 0;
|
||||
counts["Error"] = 0;
|
||||
counts["Warning"] = 0;
|
||||
counts["Information"] = 0;
|
||||
counts["Debug"] = 0;
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <tbody class=\"logBody\">\r\n");
|
||||
#line 213 "LogPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 213 "LogPage.cshtml"
|
||||
if (!activity.RepresentsScope)
|
||||
{
|
||||
// message not within a scope
|
||||
var logInfo = activity.Root.Messages.FirstOrDefault();
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 217 "LogPage.cshtml"
|
||||
Write(LogRow(logInfo, 0));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 217 "LogPage.cshtml"
|
||||
|
||||
counts[logInfo.Severity.ToString()] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 222 "LogPage.cshtml"
|
||||
Write(Traverse(activity.Root, 0, counts));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 222 "LogPage.cshtml"
|
||||
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </tbody>\r\n <tbody class=\"summary\">\r\n <tr class=\"logRow\">\r\n <td>");
|
||||
#line 227 "LogPage.cshtml"
|
||||
Write(activity.Time.ToString("MM-dd-yyyy HH:mm:ss"));
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n");
|
||||
#line 228 "LogPage.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 228 "LogPage.cshtml"
|
||||
foreach (var kvp in counts)
|
||||
{
|
||||
if (string.Equals("Debug", kvp.Key)) {
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <td>");
|
||||
#line 231 "LogPage.cshtml"
|
||||
Write(kvp.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" ");
|
||||
#line 231 "LogPage.cshtml"
|
||||
Write(kvp.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("<span class=\"collapse\">v</span></td>\r\n");
|
||||
#line 232 "LogPage.cshtml"
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" <td>");
|
||||
#line 235 "LogPage.cshtml"
|
||||
Write(kvp.Value);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" ");
|
||||
#line 235 "LogPage.cshtml"
|
||||
Write(kvp.Key);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral("</td>\r\n");
|
||||
#line 236 "LogPage.cshtml"
|
||||
}
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(" </tr>\r\n </tbody>\r\n </table>\r\n </td>\r\n </tr>\r\n </tbody>\r\n");
|
||||
#line 244 "LogPage.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
WriteLiteral(@" </table>
|
||||
<script type=""text/javascript"">
|
||||
$(document).ready(function () {
|
||||
$("".logBody"").hide();
|
||||
$("".logTable > thead"").hide();
|
||||
$("".logTable > thead"").click(function () {
|
||||
$(this).closest("".logTable"").find(""tbody"").hide();
|
||||
$(this).closest("".logTable"").find("".summary"").show();
|
||||
$(this).hide();
|
||||
});
|
||||
$("".logTable > .summary"").click(function () {
|
||||
$(this).closest("".logTable"").find(""tbody"").show();
|
||||
$(this).closest("".logTable"").find(""thead"").show();
|
||||
$(this).hide();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
@using System
|
||||
@using System.Collections.Generic
|
||||
@using System.Globalization
|
||||
@using System.Linq
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm
|
||||
@using Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
@using Microsoft.AspNetCore.DiagnosticsViewPage.Views
|
||||
@using Microsoft.Extensions.Logging
|
||||
|
||||
@functions
|
||||
{
|
||||
public LogPage(LogPageModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public LogPageModel Model { get; set; }
|
||||
|
||||
public HelperResult LogRow(LogInfo log, int level)
|
||||
{
|
||||
return new HelperResult((writer) =>
|
||||
{
|
||||
if (log.Severity >= Model.Options.MinLevel &&
|
||||
(string.IsNullOrEmpty(Model.Options.NamePrefix) || log.Name.StartsWith(Model.Options.NamePrefix, StringComparison.Ordinal)))
|
||||
{
|
||||
|
||||
WriteLiteralTo(writer, " <tr class=\"logRow\">\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:MM/dd/yy}", log.Time));
|
||||
|
||||
WriteLiteralTo(writer, "</td>\r\n <td>");
|
||||
WriteTo(writer, string.Format("{0:H:mm:ss}", log.Time));
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Name}\">");
|
||||
WriteTo(writer, log.Name);
|
||||
var severity = log.Severity.ToString().ToLowerInvariant();
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td class=\"{severity}\">");
|
||||
WriteTo(writer, log.Severity);
|
||||
|
||||
WriteLiteralTo(writer, $"</td>\r\n <td title=\"{log.Message}\"> \r\n");
|
||||
|
||||
for (var i = 0; i < level; i++)
|
||||
{
|
||||
WriteLiteralTo(writer, " <span class=\"tab\"></span>\r\n");
|
||||
}
|
||||
|
||||
WriteLiteralTo(writer, " ");
|
||||
WriteTo(writer, log.Message);
|
||||
|
||||
WriteLiteralTo(writer, $"\r\n </td>\r\n <td title=\"{log.Exception}\">");
|
||||
|
||||
WriteTo(writer, log.Exception);
|
||||
|
||||
WriteLiteralTo(writer, "</td>\r\n </tr>\r\n");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HelperResult Traverse(ScopeNode node, int level, Dictionary<string, int> counts)
|
||||
{
|
||||
return new HelperResult((writer) => {
|
||||
// print start of scope
|
||||
WriteTo(writer, LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.StartTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = "Beginning " + node.State,
|
||||
}, level));
|
||||
|
||||
var messageIndex = 0;
|
||||
var childIndex = 0;
|
||||
while (messageIndex < node.Messages.Count && childIndex < node.Children.Count)
|
||||
{
|
||||
if (node.Messages[messageIndex].Time < node.Children[childIndex].StartTime)
|
||||
{
|
||||
WriteTo(writer, LogRow(node.Messages[messageIndex], level));
|
||||
|
||||
counts[node.Messages[messageIndex].Severity.ToString()]++;
|
||||
messageIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTo(writer, Traverse(node.Children[childIndex], level + 1, counts));
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
if (messageIndex < node.Messages.Count)
|
||||
{
|
||||
for (var i = messageIndex; i < node.Messages.Count; i++)
|
||||
{
|
||||
WriteTo(writer, LogRow(node.Messages[i], level));
|
||||
counts[node.Messages[i].Severity.ToString()]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = childIndex; i < node.Children.Count; i++)
|
||||
{
|
||||
WriteTo(writer, Traverse(node.Children[i], level + 1, counts));
|
||||
}
|
||||
}
|
||||
// print end of scope
|
||||
WriteTo(writer, LogRow(new LogInfo()
|
||||
{
|
||||
Name = node.Name,
|
||||
Time = node.EndTime,
|
||||
Severity = LogLevel.Debug,
|
||||
Message = string.Format("Completed {0} in {1}ms", node.State, node.EndTime - node.StartTime)
|
||||
}, level));
|
||||
});
|
||||
}
|
||||
}
|
||||
@{
|
||||
Response.ContentType = "text/html";
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>ASP.NET Core Logs</title>
|
||||
<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js"></script>
|
||||
<style>
|
||||
<%$ include: LogPage.css %>
|
||||
<%$ include: Shared.css %>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ASP.NET Core Logs</h1>
|
||||
<form id="viewOptions" method="get">
|
||||
<select name="level">
|
||||
@foreach (var severity in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var severityInt = (int)severity;
|
||||
if ((int)Model.Options.MinLevel == severityInt)
|
||||
{
|
||||
<option value="@severityInt" selected="selected">@severity</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@severityInt">@severity</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<input type="text" name="name" value="@Model.Options.NamePrefix" />
|
||||
<input type="submit" value="filter" />
|
||||
</form>
|
||||
<form id="clear" method="post" action="">
|
||||
<button type="submit" name="clear" value="1">Clear Logs</button>
|
||||
</form>
|
||||
|
||||
<table id="requestTable">
|
||||
<thead id="requestHeader">
|
||||
<tr>
|
||||
<th class="path">Path</th>
|
||||
<th class="method">Method</th>
|
||||
<th class="host">Host</th>
|
||||
<th class="statusCode">Status Code</th>
|
||||
<th class="logs">Logs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<colgroup>
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
<col />
|
||||
</colgroup>
|
||||
@foreach (var activity in Model.Activities.Reverse())
|
||||
{
|
||||
<tbody>
|
||||
<tr class="requestRow">
|
||||
@{
|
||||
var activityPath = Model.Path.Value + "/" + activity.Id;
|
||||
if (activity.HttpInfo != null)
|
||||
{
|
||||
<td><a href="@activityPath" title="@activity.HttpInfo.Path">@activity.HttpInfo.Path</a></td>
|
||||
<td>@activity.HttpInfo.Method</td>
|
||||
<td>@activity.HttpInfo.Host</td>
|
||||
<td>@activity.HttpInfo.StatusCode</td>
|
||||
}
|
||||
else if (activity.RepresentsScope)
|
||||
{
|
||||
<td colspan="4"><a href="@activityPath" title="@activity.Root.State">@activity.Root.State</a></td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td colspan="4"><a href="@activityPath">Non-scope Log</a></td>
|
||||
}
|
||||
}
|
||||
<td class="logTd">
|
||||
<table class="logTable">
|
||||
<thead class="logHeader">
|
||||
<tr class="headerRow">
|
||||
<th class="date">Date</th>
|
||||
<th class="time">Time</th>
|
||||
<th class="name">Name</th>
|
||||
<th class="severity">Severity</th>
|
||||
<th class="state">State</th>
|
||||
<th>Error<span class="collapse">^</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@{
|
||||
var counts = new Dictionary<string, int>();
|
||||
counts["Critical"] = 0;
|
||||
counts["Error"] = 0;
|
||||
counts["Warning"] = 0;
|
||||
counts["Information"] = 0;
|
||||
counts["Debug"] = 0;
|
||||
}
|
||||
<tbody class="logBody">
|
||||
@if (!activity.RepresentsScope)
|
||||
{
|
||||
// message not within a scope
|
||||
var logInfo = activity.Root.Messages.FirstOrDefault();
|
||||
@LogRow(logInfo, 0)
|
||||
counts[logInfo.Severity.ToString()] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@Traverse(activity.Root, 0, counts)
|
||||
}
|
||||
</tbody>
|
||||
<tbody class="summary">
|
||||
<tr class="logRow">
|
||||
<td>@activity.Time.ToString("MM-dd-yyyy HH:mm:ss")</td>
|
||||
@foreach (var kvp in counts)
|
||||
{
|
||||
if (string.Equals("Debug", kvp.Key)) {
|
||||
<td>@kvp.Value @kvp.Key<span class="collapse">v</span></td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td>@kvp.Value @kvp.Key</td>
|
||||
}
|
||||
}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
}
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$(".logBody").hide();
|
||||
$(".logTable > thead").hide();
|
||||
$(".logTable > thead").click(function () {
|
||||
$(this).closest(".logTable").find("tbody").hide();
|
||||
$(this).closest(".logTable").find(".summary").show();
|
||||
$(this).hide();
|
||||
});
|
||||
$(".logTable > .summary").click(function () {
|
||||
$(this).closest(".logTable").find("tbody").show();
|
||||
$(this).closest(".logTable").find("thead").show();
|
||||
$(this).hide();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
body {
|
||||
font-size: .813em;
|
||||
white-space: nowrap;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
col:nth-child(2n) {
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0px auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
thead {
|
||||
font-size: 1em;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
tr {
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
#requestHeader {
|
||||
border-bottom: solid 1px gray;
|
||||
border-top: solid 1px gray;
|
||||
margin-bottom: 2px;
|
||||
font-size: 1em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
color: black;
|
||||
float: right;
|
||||
font-weight: normal;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.date, .time {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.logHeader {
|
||||
border-bottom: 1px solid lightgray;
|
||||
color: gray;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.logState {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.logTd {
|
||||
border-left: 1px solid gray;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.logs {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.logRow:hover {
|
||||
background-color: #D6F5FF;
|
||||
}
|
||||
|
||||
.requestRow>td {
|
||||
border-bottom: solid 1px gray;
|
||||
}
|
||||
|
||||
.severity {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.summary {
|
||||
color: black;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
.summary>th {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tab {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
#viewOptions {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
#viewOptions > * {
|
||||
margin: 5px;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Diagnostics.Elm.Views
|
||||
{
|
||||
[Obsolete("This type is for internal use only and will be removed in a future version.")]
|
||||
public class LogPageModel
|
||||
{
|
||||
public IEnumerable<ActivityContext> Activities { get; set; }
|
||||
|
||||
public ViewOptions Options { get; set; }
|
||||
|
||||
public PathString Path { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Arial, Helvtica, sans-serif;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Segoe UI', Helvetica, sans-serif;
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.critical {
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.information {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.debug {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: orange;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Arial, Helvtica, sans-serif;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Segoe UI', Helvetica, sans-serif;
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
td {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.critical {
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.information {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.debug {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: orange;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,33 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core middleware for exception handling, exception display pages, and diagnostics information. Includes developer exception page middleware, exception handler middleware, runtime info middleware, status code page middleware, and welcome page middleware</Description>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>aspnetcore;diagnostics</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\shared\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Diagnostics.Abstractions\Microsoft.AspNetCore.Diagnostics.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(MicrosoftAspNetCoreHostingAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="$(MicrosoftAspNetCoreHttpExtensionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="$(MicrosoftAspNetCoreWebUtilitiesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="$(MicrosoftExtensionsFileProvidersPhysicalPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.RazorViews.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsRazorViewsSourcesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.StackTrace.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsStackTraceSourcesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.TypeNameHelper.Sources" PrivateAssets="All" Version="$(MicrosoftExtensionsTypeNameHelperSourcesPackageVersion)" />
|
||||
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourcePackageVersion)" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
public sealed class HealthCheckContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="HealthCheckRegistration"/> of the currently executing <see cref="IHealthCheck"/>.
|
||||
/// </summary>
|
||||
public HealthCheckRegistration Registration { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent the registration information associated with an <see cref="IHealthCheck"/> implementation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The health check registration is provided as a separate object so that application developers can customize
|
||||
/// how health check implementations are configured.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The registration is provided to an <see cref="IHealthCheck"/> implementation during execution through
|
||||
/// <see cref="HealthCheckContext.Registration"/>. This allows a health check implementation to access named
|
||||
/// options or perform other operations based on the registered name.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class HealthCheckRegistration
|
||||
{
|
||||
private Func<IServiceProvider, IHealthCheck> _factory;
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HealthCheckRegistration"/> for an existing <see cref="IHealthCheck"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="name">The health check name.</param>
|
||||
/// <param name="instance">The <see cref="IHealthCheck"/> instance.</param>
|
||||
/// <param name="failureStatus">
|
||||
/// The <see cref="HealthStatus"/> that should be reported upon failure of the health check. If the provided value
|
||||
/// is <c>null</c>, then <see cref="HealthStatus.Unhealthy"/> will be reported.
|
||||
/// </param>
|
||||
/// <param name="tags">A list of tags that can be used for filtering health checks.</param>
|
||||
public HealthCheckRegistration(string name, IHealthCheck instance, HealthStatus? failureStatus, IEnumerable<string> tags)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instance));
|
||||
}
|
||||
|
||||
Name = name;
|
||||
FailureStatus = failureStatus ?? HealthStatus.Unhealthy;
|
||||
Tags = new HashSet<string>(tags ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase);
|
||||
Factory = (_) => instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HealthCheckRegistration"/> for an existing <see cref="IHealthCheck"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="name">The health check name.</param>
|
||||
/// <param name="factory">A delegate used to create the <see cref="IHealthCheck"/> instance.</param>
|
||||
/// <param name="failureStatus">
|
||||
/// The <see cref="HealthStatus"/> that should be reported when the health check reports a failure. If the provided value
|
||||
/// is <c>null</c>, then <see cref="HealthStatus.Unhealthy"/> will be reported.
|
||||
/// </param>
|
||||
/// <param name="tags">A list of tags that can be used for filtering health checks.</param>
|
||||
public HealthCheckRegistration(
|
||||
string name,
|
||||
Func<IServiceProvider, IHealthCheck> factory,
|
||||
HealthStatus? failureStatus,
|
||||
IEnumerable<string> tags)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (factory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(factory));
|
||||
}
|
||||
|
||||
Name = name;
|
||||
FailureStatus = failureStatus ?? HealthStatus.Unhealthy;
|
||||
Tags = new HashSet<string>(tags ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase);
|
||||
Factory = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a delegate used to create the <see cref="IHealthCheck"/> instance.
|
||||
/// </summary>
|
||||
public Func<IServiceProvider, IHealthCheck> Factory
|
||||
{
|
||||
get => _factory;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
_factory = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="HealthStatus"/> that should be reported upon failure of the health check.
|
||||
/// </summary>
|
||||
public HealthStatus FailureStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the health check name.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of tags that can be used for filtering health checks.
|
||||
/// </summary>
|
||||
public ISet<string> Tags { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of a health check.
|
||||
/// </summary>
|
||||
public struct HealthCheckResult
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, object> _emptyReadOnlyDictionary = new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HealthCheckResult"/> with the specified values for <paramref name="status"/>,
|
||||
/// <paramref name="exception"/>, <paramref name="description"/>, and <paramref name="data"/>.
|
||||
/// </summary>
|
||||
/// <param name="status">A value indicating the status of the component that was checked.</param>
|
||||
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
|
||||
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).</param>
|
||||
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
|
||||
public HealthCheckResult(HealthStatus status, string description = null, Exception exception = null, IReadOnlyDictionary<string, object> data = null)
|
||||
{
|
||||
Status = status;
|
||||
Description = description;
|
||||
Exception = exception;
|
||||
Data = data ?? _emptyReadOnlyDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets additional key-value pairs describing the health of the component.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, object> Data { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a human-readable description of the status of the component that was checked.
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).
|
||||
/// </summary>
|
||||
public Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating the status of the component that was checked.
|
||||
/// </summary>
|
||||
public HealthStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="HealthCheckResult"/> representing a healthy component.
|
||||
/// </summary>
|
||||
/// <param name="description">A human-readable description of the status of the component that was checked. Optional.</param>
|
||||
/// <param name="data">Additional key-value pairs describing the health of the component. Optional.</param>
|
||||
/// <returns>A <see cref="HealthCheckResult"/> representing a healthy component.</returns>
|
||||
public static HealthCheckResult Healthy(string description = null, IReadOnlyDictionary<string, object> data = null)
|
||||
{
|
||||
return new HealthCheckResult(status: HealthStatus.Healthy, description, exception: null, data);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="HealthCheckResult"/> representing a degraded component.
|
||||
/// </summary>
|
||||
/// <param name="description">A human-readable description of the status of the component that was checked. Optional.</param>
|
||||
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status. Optional.</param>
|
||||
/// <param name="data">Additional key-value pairs describing the health of the component. Optional.</param>
|
||||
/// <returns>A <see cref="HealthCheckResult"/> representing a degraged component.</returns>
|
||||
public static HealthCheckResult Degraded(string description = null, Exception exception = null, IReadOnlyDictionary<string, object> data = null)
|
||||
{
|
||||
return new HealthCheckResult(status: HealthStatus.Degraded, description, exception: null, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
|
||||
/// </summary>
|
||||
/// <param name="description">A human-readable description of the status of the component that was checked. Optional.</param>
|
||||
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status. Optional.</param>
|
||||
/// <param name="data">Additional key-value pairs describing the health of the component. Optional.</param>
|
||||
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
|
||||
public static HealthCheckResult Unhealthy(string description = null, Exception exception = null, IReadOnlyDictionary<string, object> data = null)
|
||||
{
|
||||
return new HealthCheckResult(status: HealthStatus.Unhealthy, description, exception, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of executing a group of <see cref="IHealthCheck"/> instances.
|
||||
/// </summary>
|
||||
public sealed class HealthReport
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new <see cref="HealthReport"/> from the specified results.
|
||||
/// </summary>
|
||||
/// <param name="entries">A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.</param>
|
||||
/// <param name="totalDuration">A value indicating the time the health check service took to execute.</param>
|
||||
public HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries, TimeSpan totalDuration)
|
||||
{
|
||||
Entries = entries;
|
||||
Status = CalculateAggregateStatus(entries.Values);
|
||||
TotalDuration = totalDuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The keys in this dictionary map the name of each executed health check to a <see cref="HealthReportEntry"/> for the
|
||||
/// result data retruned from the corresponding health check.
|
||||
/// </remarks>
|
||||
public IReadOnlyDictionary<string, HealthReportEntry> Entries { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="HealthStatus"/> representing the aggregate status of all the health checks. The value of <see cref="Status"/>
|
||||
/// will be the most servere status reported by a health check. If no checks were executed, the value is always <see cref="HealthStatus.Healthy"/>.
|
||||
/// </summary>
|
||||
public HealthStatus Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time the health check service took to execute.
|
||||
/// </summary>
|
||||
public TimeSpan TotalDuration { get; }
|
||||
|
||||
private HealthStatus CalculateAggregateStatus(IEnumerable<HealthReportEntry> entries)
|
||||
{
|
||||
// This is basically a Min() check, but we know the possible range, so we don't need to walk the whole list
|
||||
var currentValue = HealthStatus.Healthy;
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (currentValue > entry.Status)
|
||||
{
|
||||
currentValue = entry.Status;
|
||||
}
|
||||
|
||||
if (currentValue == HealthStatus.Unhealthy)
|
||||
{
|
||||
// Game over, man! Game over!
|
||||
// (We hit the worst possible status, so there's no need to keep iterating)
|
||||
return currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
return currentValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an entry in a <see cref="HealthReport"/>. Corresponds to the result of a single <see cref="IHealthCheck"/>.
|
||||
/// </summary>
|
||||
public struct HealthReportEntry
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, object> _emptyReadOnlyDictionary = new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HealthReportEntry"/> with the specified values for <paramref name="status"/>, <paramref name="exception"/>,
|
||||
/// <paramref name="description"/>, and <paramref name="data"/>.
|
||||
/// </summary>
|
||||
/// <param name="status">A value indicating the health status of the component that was checked.</param>
|
||||
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
|
||||
/// <param name="duration">A value indicating the health execution duration.</param>
|
||||
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).</param>
|
||||
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
|
||||
public HealthReportEntry(HealthStatus status, string description, TimeSpan duration, Exception exception, IReadOnlyDictionary<string, object> data)
|
||||
{
|
||||
Status = status;
|
||||
Description = description;
|
||||
Duration = duration;
|
||||
Exception = exception;
|
||||
Data = data ?? _emptyReadOnlyDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets additional key-value pairs describing the health of the component.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, object> Data { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a human-readable description of the status of the component that was checked.
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the health check execution duration.
|
||||
/// </summary>
|
||||
public TimeSpan Duration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="System.Exception"/> representing the exception that was thrown when checking for status (if any).
|
||||
/// </summary>
|
||||
public Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the health status of the component that was checked.
|
||||
/// </summary>
|
||||
public HealthStatus Status { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the reported status of a health check result.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A status of <see cref="Unhealthy"/> should be considered the default value for a failing health check. Application
|
||||
/// developers may configure a health check to report a different status as desired.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The values of this enum or ordered from least healthy to most healthy. So <see cref="HealthStatus.Degraded"/> is
|
||||
/// greater than <see cref="HealthStatus.Unhealthy"/> but less than <see cref="HealthStatus.Healthy"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public enum HealthStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the health check determined that the component was unhealthy, or an unhandled
|
||||
/// exception was thrown while executing the health check.
|
||||
/// </summary>
|
||||
Unhealthy = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the health check determined that the component was in a degraded state.
|
||||
/// </summary>
|
||||
Degraded = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the health check determined that the component was healthy.
|
||||
/// </summary>
|
||||
Healthy = 2,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a health check, which can be used to check the status of a component in the application, such as a backend service, database or some internal
|
||||
/// state.
|
||||
/// </summary>
|
||||
public interface IHealthCheck
|
||||
{
|
||||
/// <summary>
|
||||
/// Runs the health check, returning the status of the component being checked.
|
||||
/// </summary>
|
||||
/// <param name="context">A context object associated with the current execution.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the health check.</param>
|
||||
/// <returns>A <see cref="Task{HealthCheckResult}"/> that completes when the health check has finished, yielding the status of the component being checked.</returns>
|
||||
Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a publisher of <see cref="HealthReport"/> information.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The default health checks implementation provided an <c>IHostedService</c> implementation that can
|
||||
/// be used to execute health checks at regular intervals and provide the resulting <see cref="HealthReport"/>
|
||||
/// data to all registered <see cref="IHealthCheckPublisher"/> instances.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// To provide an <see cref="IHealthCheckPublisher"/> implementation, register an instance or type as a singleton
|
||||
/// service in the dependency injection container.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <see cref="IHealthCheckPublisher"/> instances are provided with a <see cref="HealthReport"/> after executing
|
||||
/// health checks in a background thread. The use of <see cref="IHealthCheckPublisher"/> depend on hosting in
|
||||
/// an application using <c>IWebHost</c> or generic host (<c>IHost</c>). Execution of <see cref="IHealthCheckPublisher"/>
|
||||
/// instance is not related to execution of health checks via a middleware.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public interface IHealthCheckPublisher
|
||||
{
|
||||
/// <summary>
|
||||
/// Publishes the provided <paramref name="report"/>.
|
||||
/// </summary>
|
||||
/// <param name="report">The <see cref="HealthReport"/>. The result of executing a set of health checks.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
||||
/// <returns>A <see cref="Task"/> which will complete when publishing is complete.</returns>
|
||||
Task PublishAsync(HealthReport report, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Abstractions for defining health checks in .NET applications
|
||||
|
||||
Commonly Used Types
|
||||
Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck
|
||||
</Description>
|
||||
<RootNamespace>Microsoft.Extensions.Diagnostics.HealthChecks</RootNamespace>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>diagnostics;healthchecks</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"AssemblyIdentity": "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
|
||||
"Types": [
|
||||
]
|
||||
}
|
||||
|
|
@ -1,304 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
internal class DefaultHealthCheckService : HealthCheckService
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private readonly IOptions<HealthCheckServiceOptions> _options;
|
||||
private readonly ILogger<DefaultHealthCheckService> _logger;
|
||||
|
||||
public DefaultHealthCheckService(
|
||||
IServiceScopeFactory scopeFactory,
|
||||
IOptions<HealthCheckServiceOptions> options,
|
||||
ILogger<DefaultHealthCheckService> logger)
|
||||
{
|
||||
_scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
// We're specifically going out of our way to do this at startup time. We want to make sure you
|
||||
// get any kind of health-check related error as early as possible. Waiting until someone
|
||||
// actually tries to **run** health checks would be real baaaaad.
|
||||
ValidateRegistrations(_options.Value.Registrations);
|
||||
}
|
||||
public override async Task<HealthReport> CheckHealthAsync(
|
||||
Func<HealthCheckRegistration, bool> predicate,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var registrations = _options.Value.Registrations;
|
||||
|
||||
using (var scope = _scopeFactory.CreateScope())
|
||||
{
|
||||
var context = new HealthCheckContext();
|
||||
var entries = new Dictionary<string, HealthReportEntry>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var totalTime = ValueStopwatch.StartNew();
|
||||
Log.HealthCheckProcessingBegin(_logger);
|
||||
|
||||
foreach (var registration in registrations)
|
||||
{
|
||||
if (predicate != null && !predicate(registration))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var healthCheck = registration.Factory(scope.ServiceProvider);
|
||||
|
||||
// If the health check does things like make Database queries using EF or backend HTTP calls,
|
||||
// it may be valuable to know that logs it generates are part of a health check. So we start a scope.
|
||||
using (_logger.BeginScope(new HealthCheckLogScope(registration.Name)))
|
||||
{
|
||||
var stopwatch = ValueStopwatch.StartNew();
|
||||
context.Registration = registration;
|
||||
|
||||
Log.HealthCheckBegin(_logger, registration);
|
||||
|
||||
HealthReportEntry entry;
|
||||
try
|
||||
{
|
||||
var result = await healthCheck.CheckHealthAsync(context, cancellationToken);
|
||||
var duration = stopwatch.GetElapsedTime();
|
||||
|
||||
entry = new HealthReportEntry(
|
||||
status: result.Status,
|
||||
description: result.Description,
|
||||
duration: duration,
|
||||
exception: result.Exception,
|
||||
data: result.Data);
|
||||
|
||||
Log.HealthCheckEnd(_logger, registration, entry, duration);
|
||||
Log.HealthCheckData(_logger, registration, entry);
|
||||
}
|
||||
|
||||
// Allow cancellation to propagate.
|
||||
catch (Exception ex) when (ex as OperationCanceledException == null)
|
||||
{
|
||||
var duration = stopwatch.GetElapsedTime();
|
||||
entry = new HealthReportEntry(
|
||||
status: HealthStatus.Unhealthy,
|
||||
description: ex.Message,
|
||||
duration: duration,
|
||||
exception: ex,
|
||||
data: null);
|
||||
|
||||
Log.HealthCheckError(_logger, registration, ex, duration);
|
||||
}
|
||||
|
||||
entries[registration.Name] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
var totalElapsedTime = totalTime.GetElapsedTime();
|
||||
var report = new HealthReport(entries, totalElapsedTime);
|
||||
Log.HealthCheckProcessingEnd(_logger, report.Status, totalElapsedTime);
|
||||
return report;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateRegistrations(IEnumerable<HealthCheckRegistration> registrations)
|
||||
{
|
||||
// Scan the list for duplicate names to provide a better error if there are duplicates.
|
||||
var duplicateNames = registrations
|
||||
.GroupBy(c => c.Name, StringComparer.OrdinalIgnoreCase)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(g => g.Key)
|
||||
.ToList();
|
||||
|
||||
if (duplicateNames.Count > 0)
|
||||
{
|
||||
throw new ArgumentException($"Duplicate health checks were registered with the name(s): {string.Join(", ", duplicateNames)}", nameof(registrations));
|
||||
}
|
||||
}
|
||||
|
||||
internal static class EventIds
|
||||
{
|
||||
public static readonly EventId HealthCheckProcessingBegin = new EventId(100, "HealthCheckProcessingBegin");
|
||||
public static readonly EventId HealthCheckProcessingEnd = new EventId(101, "HealthCheckProcessingEnd");
|
||||
|
||||
public static readonly EventId HealthCheckBegin = new EventId(102, "HealthCheckBegin");
|
||||
public static readonly EventId HealthCheckEnd = new EventId(103, "HealthCheckEnd");
|
||||
public static readonly EventId HealthCheckError = new EventId(104, "HealthCheckError");
|
||||
public static readonly EventId HealthCheckData = new EventId(105, "HealthCheckData");
|
||||
}
|
||||
|
||||
private static class Log
|
||||
{
|
||||
private static readonly Action<ILogger, Exception> _healthCheckProcessingBegin = LoggerMessage.Define(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckProcessingBegin,
|
||||
"Running health checks");
|
||||
|
||||
private static readonly Action<ILogger, double, HealthStatus, Exception> _healthCheckProcessingEnd = LoggerMessage.Define<double, HealthStatus>(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckProcessingEnd,
|
||||
"Health check processing completed after {ElapsedMilliseconds}ms with combined status {HealthStatus}");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _healthCheckBegin = LoggerMessage.Define<string>(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckBegin,
|
||||
"Running health check {HealthCheckName}");
|
||||
|
||||
// These are separate so they can have different log levels
|
||||
private static readonly string HealthCheckEndText = "Health check {HealthCheckName} completed after {ElapsedMilliseconds}ms with status {HealthStatus} and '{HealthCheckDescription}'";
|
||||
|
||||
private static readonly Action<ILogger, string, double, HealthStatus, string, Exception> _healthCheckEndHealthy = LoggerMessage.Define<string, double, HealthStatus, string>(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckEnd,
|
||||
HealthCheckEndText);
|
||||
|
||||
private static readonly Action<ILogger, string, double, HealthStatus, string, Exception> _healthCheckEndDegraded = LoggerMessage.Define<string, double, HealthStatus, string>(
|
||||
LogLevel.Warning,
|
||||
EventIds.HealthCheckEnd,
|
||||
HealthCheckEndText);
|
||||
|
||||
private static readonly Action<ILogger, string, double, HealthStatus, string, Exception> _healthCheckEndUnhealthy = LoggerMessage.Define<string, double, HealthStatus, string>(
|
||||
LogLevel.Error,
|
||||
EventIds.HealthCheckEnd,
|
||||
HealthCheckEndText);
|
||||
|
||||
private static readonly Action<ILogger, string, double, HealthStatus, string, Exception> _healthCheckEndFailed = LoggerMessage.Define<string, double, HealthStatus, string>(
|
||||
LogLevel.Error,
|
||||
EventIds.HealthCheckEnd,
|
||||
HealthCheckEndText);
|
||||
|
||||
private static readonly Action<ILogger, string, double, Exception> _healthCheckError = LoggerMessage.Define<string, double>(
|
||||
LogLevel.Error,
|
||||
EventIds.HealthCheckError,
|
||||
"Health check {HealthCheckName} threw an unhandled exception after {ElapsedMilliseconds}ms");
|
||||
|
||||
public static void HealthCheckProcessingBegin(ILogger logger)
|
||||
{
|
||||
_healthCheckProcessingBegin(logger, null);
|
||||
}
|
||||
|
||||
public static void HealthCheckProcessingEnd(ILogger logger, HealthStatus status, TimeSpan duration)
|
||||
{
|
||||
_healthCheckProcessingEnd(logger, duration.TotalMilliseconds, status, null);
|
||||
}
|
||||
|
||||
public static void HealthCheckBegin(ILogger logger, HealthCheckRegistration registration)
|
||||
{
|
||||
_healthCheckBegin(logger, registration.Name, null);
|
||||
}
|
||||
|
||||
public static void HealthCheckEnd(ILogger logger, HealthCheckRegistration registration, HealthReportEntry entry, TimeSpan duration)
|
||||
{
|
||||
switch (entry.Status)
|
||||
{
|
||||
case HealthStatus.Healthy:
|
||||
_healthCheckEndHealthy(logger, registration.Name, duration.TotalMilliseconds, entry.Status, entry.Description, null);
|
||||
break;
|
||||
|
||||
case HealthStatus.Degraded:
|
||||
_healthCheckEndDegraded(logger, registration.Name, duration.TotalMilliseconds, entry.Status, entry.Description, null);
|
||||
break;
|
||||
|
||||
case HealthStatus.Unhealthy:
|
||||
_healthCheckEndUnhealthy(logger, registration.Name, duration.TotalMilliseconds, entry.Status, entry.Description, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void HealthCheckError(ILogger logger, HealthCheckRegistration registration, Exception exception, TimeSpan duration)
|
||||
{
|
||||
_healthCheckError(logger, registration.Name, duration.TotalMilliseconds, exception);
|
||||
}
|
||||
|
||||
public static void HealthCheckData(ILogger logger, HealthCheckRegistration registration, HealthReportEntry entry)
|
||||
{
|
||||
if (entry.Data.Count > 0 && logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Log(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckData,
|
||||
new HealthCheckDataLogValue(registration.Name, entry.Data),
|
||||
null,
|
||||
(state, ex) => state.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class HealthCheckDataLogValue : IReadOnlyList<KeyValuePair<string, object>>
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly List<KeyValuePair<string, object>> _values;
|
||||
|
||||
private string _formatted;
|
||||
|
||||
public HealthCheckDataLogValue(string name, IReadOnlyDictionary<string, object> values)
|
||||
{
|
||||
_name = name;
|
||||
_values = values.ToList();
|
||||
|
||||
// We add the name as a kvp so that you can filter by health check name in the logs.
|
||||
// This is the same parameter name used in the other logs.
|
||||
_values.Add(new KeyValuePair<string, object>("HealthCheckName", name));
|
||||
}
|
||||
|
||||
public KeyValuePair<string, object> this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
{
|
||||
throw new IndexOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
return _values[index];
|
||||
}
|
||||
}
|
||||
|
||||
public int Count => _values.Count;
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
return _values.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return _values.GetEnumerator();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (_formatted == null)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine($"Health check data for {_name}:");
|
||||
|
||||
var values = _values;
|
||||
for (var i = 0; i < values.Count; i++)
|
||||
{
|
||||
var kvp = values[i];
|
||||
builder.Append(" ");
|
||||
builder.Append(kvp.Key);
|
||||
builder.Append(": ");
|
||||
|
||||
builder.AppendLine(kvp.Value?.ToString());
|
||||
}
|
||||
|
||||
_formatted = builder.ToString();
|
||||
}
|
||||
|
||||
return _formatted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple implementation of <see cref="IHealthCheck"/> which uses a provided delegate to
|
||||
/// implement the check.
|
||||
/// </summary>
|
||||
internal sealed class DelegateHealthCheck : IHealthCheck
|
||||
{
|
||||
private readonly Func<CancellationToken, Task<HealthCheckResult>> _check;
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of <see cref="DelegateHealthCheck"/> from the specified delegate.
|
||||
/// </summary>
|
||||
/// <param name="check">A delegate which provides the code to execute when the health check is run.</param>
|
||||
public DelegateHealthCheck(Func<CancellationToken, Task<HealthCheckResult>> check)
|
||||
{
|
||||
_check = check ?? throw new ArgumentNullException(nameof(check));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the health check, returning the status of the component being checked.
|
||||
/// </summary>
|
||||
/// <param name="context">A context object associated with the current execution.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the health check.</param>
|
||||
/// <returns>A <see cref="Task{HealthCheckResult}"/> that completes when the health check has finished, yielding the status of the component being checked.</returns>
|
||||
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) => _check(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for registering <see cref="HealthCheckService"/> in an <see cref="IServiceCollection"/>.
|
||||
/// </summary>
|
||||
public static class HealthCheckServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="HealthCheckService"/> to the container, using the provided delegate to register
|
||||
/// health checks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This operation is idempotent - multiple invocations will still only result in a single
|
||||
/// <see cref="HealthCheckService"/> instance in the <see cref="IServiceCollection"/>. It can be invoked
|
||||
/// multiple times in order to get access to the <see cref="IHealthChecksBuilder"/> in multiple places.
|
||||
/// </remarks>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to add the <see cref="HealthCheckService"/> to.</param>
|
||||
/// <returns>An instance of <see cref="IHealthChecksBuilder"/> from which health checks can be registered.</returns>
|
||||
public static IHealthChecksBuilder AddHealthChecks(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddSingleton<HealthCheckService, DefaultHealthCheckService>();
|
||||
services.TryAddSingleton<IHostedService, HealthCheckPublisherHostedService>();
|
||||
return new HealthChecksBuilder(services);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
internal class HealthChecksBuilder : IHealthChecksBuilder
|
||||
{
|
||||
public HealthChecksBuilder(IServiceCollection services)
|
||||
{
|
||||
Services = services;
|
||||
}
|
||||
|
||||
public IServiceCollection Services { get; }
|
||||
|
||||
public IHealthChecksBuilder Add(HealthCheckRegistration registration)
|
||||
{
|
||||
if (registration == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(registration));
|
||||
}
|
||||
|
||||
Services.Configure<HealthCheckServiceOptions>(options =>
|
||||
{
|
||||
options.Registrations.Add(registration);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides basic extension methods for registering <see cref="IHealthCheck"/> instances in an <see cref="IHealthChecksBuilder"/>.
|
||||
/// </summary>
|
||||
public static class HealthChecksBuilderAddCheckExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="instance">An <see cref="IHealthCheck"/> instance.</param>
|
||||
/// <param name="failureStatus">
|
||||
/// The <see cref="HealthStatus"/> that should be reported when the health check reports a failure. If the provided value
|
||||
/// is <c>null</c>, then <see cref="HealthStatus.Unhealthy"/> will be reported.
|
||||
/// </param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
public static IHealthChecksBuilder AddCheck(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
IHealthCheck instance,
|
||||
HealthStatus? failureStatus = null,
|
||||
IEnumerable<string> tags = null)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instance));
|
||||
}
|
||||
|
||||
return builder.Add(new HealthCheckRegistration(name, instance, failureStatus, tags));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The health check implementation type.</typeparam>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="failureStatus">
|
||||
/// The <see cref="HealthStatus"/> that should be reported when the health check reports a failure. If the provided value
|
||||
/// is <c>null</c>, then <see cref="HealthStatus.Unhealthy"/> will be reported.
|
||||
/// </param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
/// <remarks>
|
||||
/// This method will use <see cref="ActivatorUtilities.GetServiceOrCreateInstance{T}(IServiceProvider)"/> to create the health check
|
||||
/// instance when needed. If a service of type <typeparamref name="T"/> is registred in the dependency injection container
|
||||
/// with any liftime it will be used. Otherwise an instance of type <typeparamref name="T"/> will be constructed with
|
||||
/// access to services from the dependency injection container.
|
||||
/// </remarks>
|
||||
public static IHealthChecksBuilder AddCheck<T>(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
HealthStatus? failureStatus = null,
|
||||
IEnumerable<string> tags = null) where T : class, IHealthCheck
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
return builder.Add(new HealthCheckRegistration(name, s => ActivatorUtilities.GetServiceOrCreateInstance<T>(s), failureStatus, tags));
|
||||
}
|
||||
|
||||
// NOTE: AddTypeActivatedCheck has overloads rather than default parameters values, because default parameter values don't
|
||||
// play super well with params.
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new type activated health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The health check implementation type.</typeparam>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="args">Additional arguments to provide to the constructor.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
/// <remarks>
|
||||
/// This method will use <see cref="ActivatorUtilities.CreateInstance{T}(IServiceProvider, object[])"/> to create the health check
|
||||
/// instance when needed. Additional arguments can be provided to the constructor via <paramref name="args"/>.
|
||||
/// </remarks>
|
||||
public static IHealthChecksBuilder AddTypeActivatedCheck<T>(this IHealthChecksBuilder builder, string name, params object[] args) where T : class, IHealthCheck
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
return AddTypeActivatedCheck<T>(builder, name, failureStatus: null, tags: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new type activated health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The health check implementation type.</typeparam>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="failureStatus">
|
||||
/// The <see cref="HealthStatus"/> that should be reported when the health check reports a failure. If the provided value
|
||||
/// is <c>null</c>, then <see cref="HealthStatus.Unhealthy"/> will be reported.
|
||||
/// </param>
|
||||
/// <param name="args">Additional arguments to provide to the constructor.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
/// <remarks>
|
||||
/// This method will use <see cref="ActivatorUtilities.CreateInstance{T}(IServiceProvider, object[])"/> to create the health check
|
||||
/// instance when needed. Additional arguments can be provided to the constructor via <paramref name="args"/>.
|
||||
/// </remarks>
|
||||
public static IHealthChecksBuilder AddTypeActivatedCheck<T>(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
HealthStatus? failureStatus,
|
||||
params object[] args) where T : class, IHealthCheck
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
return AddTypeActivatedCheck<T>(builder, name, failureStatus, tags: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new type activated health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The health check implementation type.</typeparam>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="failureStatus">
|
||||
/// The <see cref="HealthStatus"/> that should be reported when the health check reports a failure. If the provided value
|
||||
/// is <c>null</c>, then <see cref="HealthStatus.Unhealthy"/> will be reported.
|
||||
/// </param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <param name="args">Additional arguments to provide to the constructor.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
/// <remarks>
|
||||
/// This method will use <see cref="ActivatorUtilities.CreateInstance{T}(IServiceProvider, object[])"/> to create the health check
|
||||
/// instance when needed. Additional arguments can be provided to the constructor via <paramref name="args"/>.
|
||||
/// </remarks>
|
||||
public static IHealthChecksBuilder AddTypeActivatedCheck<T>(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
HealthStatus? failureStatus,
|
||||
IEnumerable<string> tags,
|
||||
params object[] args) where T : class, IHealthCheck
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
return builder.Add(new HealthCheckRegistration(name, s => ActivatorUtilities.CreateInstance<T>(s, args), failureStatus, tags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for registering delegates with the <see cref="IHealthChecksBuilder"/>.
|
||||
/// </summary>
|
||||
public static class HealthChecksBuilderDelegateExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <param name="check">A delegate that provides the health check implementation.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
public static IHealthChecksBuilder AddCheck(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
Func<HealthCheckResult> check,
|
||||
IEnumerable<string> tags = null)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (check == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(check));
|
||||
}
|
||||
|
||||
var instance = new DelegateHealthCheck((ct) => Task.FromResult(check()));
|
||||
return builder.Add(new HealthCheckRegistration(name, instance, failureStatus: null, tags));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <param name="check">A delegate that provides the health check implementation.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
public static IHealthChecksBuilder AddCheck(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
Func<CancellationToken, HealthCheckResult> check,
|
||||
IEnumerable<string> tags = null)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (check == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(check));
|
||||
}
|
||||
|
||||
var instance = new DelegateHealthCheck((ct) => Task.FromResult(check(ct)));
|
||||
return builder.Add(new HealthCheckRegistration(name, instance, failureStatus: null, tags));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <param name="check">A delegate that provides the health check implementation.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
public static IHealthChecksBuilder AddAsyncCheck(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
Func<Task<HealthCheckResult>> check,
|
||||
IEnumerable<string> tags = null)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (check == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(check));
|
||||
}
|
||||
|
||||
var instance = new DelegateHealthCheck((ct) => check());
|
||||
return builder.Add(new HealthCheckRegistration(name, instance, failureStatus: null, tags));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new health check with the specified name and implementation.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
|
||||
/// <param name="name">The name of the health check.</param>
|
||||
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
|
||||
/// <param name="check">A delegate that provides the health check implementation.</param>
|
||||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
|
||||
public static IHealthChecksBuilder AddAsyncCheck(
|
||||
this IHealthChecksBuilder builder,
|
||||
string name,
|
||||
Func<CancellationToken, Task<HealthCheckResult>> check,
|
||||
IEnumerable<string> tags = null)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (check == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(check));
|
||||
}
|
||||
|
||||
var instance = new DelegateHealthCheck((ct) => check(ct));
|
||||
return builder.Add(new HealthCheckRegistration(name, instance, failureStatus: null, tags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
/// A builder used to register health checks.
|
||||
/// </summary>
|
||||
public interface IHealthChecksBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a <see cref="HealthCheckRegistration"/> for a health check.
|
||||
/// </summary>
|
||||
/// <param name="registration">The <see cref="HealthCheckRegistration"/>.</param>
|
||||
IHealthChecksBuilder Add(HealthCheckRegistration registration);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IServiceCollection"/> into which <see cref="IHealthCheck"/> instances should be registered.
|
||||
/// </summary>
|
||||
IServiceCollection Services { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
internal class HealthCheckLogScope : IReadOnlyList<KeyValuePair<string, object>>
|
||||
{
|
||||
public string HealthCheckName { get; }
|
||||
|
||||
int IReadOnlyCollection<KeyValuePair<string, object>>.Count { get; } = 1;
|
||||
|
||||
KeyValuePair<string, object> IReadOnlyList<KeyValuePair<string, object>>.this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
return new KeyValuePair<string, object>(nameof(HealthCheckName), HealthCheckName);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="HealthCheckLogScope"/> with the provided name.
|
||||
/// </summary>
|
||||
/// <param name="healthCheckName">The name of the health check being executed.</param>
|
||||
public HealthCheckLogScope(string healthCheckName)
|
||||
{
|
||||
HealthCheckName = healthCheckName;
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
|
||||
{
|
||||
yield return new KeyValuePair<string, object>(nameof(HealthCheckName), HealthCheckName);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<KeyValuePair<string, object>>)this).GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,262 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
internal sealed class HealthCheckPublisherHostedService : IHostedService
|
||||
{
|
||||
private readonly HealthCheckService _healthCheckService;
|
||||
private readonly IOptions<HealthCheckPublisherOptions> _options;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IHealthCheckPublisher[] _publishers;
|
||||
|
||||
private CancellationTokenSource _stopping;
|
||||
private Timer _timer;
|
||||
|
||||
public HealthCheckPublisherHostedService(
|
||||
HealthCheckService healthCheckService,
|
||||
IOptions<HealthCheckPublisherOptions> options,
|
||||
ILogger<HealthCheckPublisherHostedService> logger,
|
||||
IEnumerable<IHealthCheckPublisher> publishers)
|
||||
{
|
||||
if (healthCheckService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(healthCheckService));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (publishers == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(publishers));
|
||||
}
|
||||
|
||||
_healthCheckService = healthCheckService;
|
||||
_options = options;
|
||||
_logger = logger;
|
||||
_publishers = publishers.ToArray();
|
||||
|
||||
_stopping = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
internal bool IsStopping => _stopping.IsCancellationRequested;
|
||||
|
||||
internal bool IsTimerRunning => _timer != null;
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_publishers.Length == 0)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// IMPORTANT - make sure this is the last thing that happens in this method. The timer can
|
||||
// fire before other code runs.
|
||||
_timer = NonCapturingTimer.Create(Timer_Tick, null, dueTime: _options.Value.Delay, period: _options.Value.Period);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
_stopping.Cancel();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore exceptions thrown as a result of a cancellation.
|
||||
}
|
||||
|
||||
if (_publishers.Length == 0)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
_timer?.Dispose();
|
||||
_timer = null;
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// Yes, async void. We need to be async. We need to be void. We handle the exceptions in RunAsync
|
||||
private async void Timer_Tick(object state)
|
||||
{
|
||||
await RunAsync();
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal async Task RunAsync()
|
||||
{
|
||||
var duration = ValueStopwatch.StartNew();
|
||||
Logger.HealthCheckPublisherProcessingBegin(_logger);
|
||||
|
||||
CancellationTokenSource cancellation = null;
|
||||
try
|
||||
{
|
||||
var timeout = _options.Value.Timeout;
|
||||
|
||||
cancellation = CancellationTokenSource.CreateLinkedTokenSource(_stopping.Token);
|
||||
cancellation.CancelAfter(timeout);
|
||||
|
||||
await RunAsyncCore(cancellation.Token);
|
||||
|
||||
Logger.HealthCheckPublisherProcessingEnd(_logger, duration.GetElapsedTime());
|
||||
}
|
||||
catch (OperationCanceledException) when (IsStopping)
|
||||
{
|
||||
// This is a cancellation - if the app is shutting down we want to ignore it. Otherwise, it's
|
||||
// a timeout and we want to log it.
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// This is an error, publishing failed.
|
||||
Logger.HealthCheckPublisherProcessingEnd(_logger, duration.GetElapsedTime(), ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cancellation.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunAsyncCore(CancellationToken cancellationToken)
|
||||
{
|
||||
// Forcibly yield - we want to unblock the timer thread.
|
||||
await Task.Yield();
|
||||
|
||||
// The health checks service does it's own logging, and doesn't throw exceptions.
|
||||
var report = await _healthCheckService.CheckHealthAsync(_options.Value.Predicate, cancellationToken);
|
||||
|
||||
var publishers = _publishers;
|
||||
var tasks = new Task[publishers.Length];
|
||||
for (var i = 0; i < publishers.Length; i++)
|
||||
{
|
||||
tasks[i] = RunPublisherAsync(publishers[i], report, cancellationToken);
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private async Task RunPublisherAsync(IHealthCheckPublisher publisher, HealthReport report, CancellationToken cancellationToken)
|
||||
{
|
||||
var duration = ValueStopwatch.StartNew();
|
||||
|
||||
try
|
||||
{
|
||||
Logger.HealthCheckPublisherBegin(_logger, publisher);
|
||||
|
||||
await publisher.PublishAsync(report, cancellationToken);
|
||||
Logger.HealthCheckPublisherEnd(_logger, publisher, duration.GetElapsedTime());
|
||||
}
|
||||
catch (OperationCanceledException) when (IsStopping)
|
||||
{
|
||||
// This is a cancellation - if the app is shutting down we want to ignore it. Otherwise, it's
|
||||
// a timeout and we want to log it.
|
||||
}
|
||||
catch (OperationCanceledException ocex)
|
||||
{
|
||||
Logger.HealthCheckPublisherTimeout(_logger, publisher, duration.GetElapsedTime());
|
||||
throw ocex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.HealthCheckPublisherError(_logger, publisher, duration.GetElapsedTime(), ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class EventIds
|
||||
{
|
||||
public static readonly EventId HealthCheckPublisherProcessingBegin = new EventId(100, "HealthCheckPublisherProcessingBegin");
|
||||
public static readonly EventId HealthCheckPublisherProcessingEnd = new EventId(101, "HealthCheckPublisherProcessingEnd");
|
||||
public static readonly EventId HealthCheckPublisherProcessingError = new EventId(101, "HealthCheckPublisherProcessingError");
|
||||
|
||||
public static readonly EventId HealthCheckPublisherBegin = new EventId(102, "HealthCheckPublisherBegin");
|
||||
public static readonly EventId HealthCheckPublisherEnd = new EventId(103, "HealthCheckPublisherEnd");
|
||||
public static readonly EventId HealthCheckPublisherError = new EventId(104, "HealthCheckPublisherError");
|
||||
public static readonly EventId HealthCheckPublisherTimeout = new EventId(104, "HealthCheckPublisherTimeout");
|
||||
}
|
||||
|
||||
private static class Logger
|
||||
{
|
||||
private static readonly Action<ILogger, Exception> _healthCheckPublisherProcessingBegin = LoggerMessage.Define(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckPublisherProcessingBegin,
|
||||
"Running health check publishers");
|
||||
|
||||
private static readonly Action<ILogger, double, Exception> _healthCheckPublisherProcessingEnd = LoggerMessage.Define<double>(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckPublisherProcessingEnd,
|
||||
"Health check publisher processing completed after {ElapsedMilliseconds}ms");
|
||||
|
||||
private static readonly Action<ILogger, IHealthCheckPublisher, Exception> _healthCheckPublisherBegin = LoggerMessage.Define<IHealthCheckPublisher>(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckPublisherBegin,
|
||||
"Running health check publisher '{HealthCheckPublisher}'");
|
||||
|
||||
private static readonly Action<ILogger, IHealthCheckPublisher, double, Exception> _healthCheckPublisherEnd = LoggerMessage.Define<IHealthCheckPublisher, double>(
|
||||
LogLevel.Debug,
|
||||
EventIds.HealthCheckPublisherEnd,
|
||||
"Health check '{HealthCheckPublisher}' completed after {ElapsedMilliseconds}ms");
|
||||
|
||||
private static readonly Action<ILogger, IHealthCheckPublisher, double, Exception> _healthCheckPublisherError = LoggerMessage.Define<IHealthCheckPublisher, double>(
|
||||
LogLevel.Error,
|
||||
EventIds.HealthCheckPublisherError,
|
||||
"Health check {HealthCheckPublisher} threw an unhandled exception after {ElapsedMilliseconds}ms");
|
||||
|
||||
private static readonly Action<ILogger, IHealthCheckPublisher, double, Exception> _healthCheckPublisherTimeout = LoggerMessage.Define<IHealthCheckPublisher, double>(
|
||||
LogLevel.Error,
|
||||
EventIds.HealthCheckPublisherTimeout,
|
||||
"Health check {HealthCheckPublisher} was canceled after {ElapsedMilliseconds}ms");
|
||||
|
||||
public static void HealthCheckPublisherProcessingBegin(ILogger logger)
|
||||
{
|
||||
_healthCheckPublisherProcessingBegin(logger, null);
|
||||
}
|
||||
|
||||
public static void HealthCheckPublisherProcessingEnd(ILogger logger, TimeSpan duration, Exception exception = null)
|
||||
{
|
||||
_healthCheckPublisherProcessingEnd(logger, duration.TotalMilliseconds, exception);
|
||||
}
|
||||
|
||||
public static void HealthCheckPublisherBegin(ILogger logger, IHealthCheckPublisher publisher)
|
||||
{
|
||||
_healthCheckPublisherBegin(logger, publisher, null);
|
||||
}
|
||||
|
||||
public static void HealthCheckPublisherEnd(ILogger logger, IHealthCheckPublisher publisher, TimeSpan duration)
|
||||
{
|
||||
_healthCheckPublisherEnd(logger, publisher, duration.TotalMilliseconds, null);
|
||||
}
|
||||
|
||||
public static void HealthCheckPublisherError(ILogger logger, IHealthCheckPublisher publisher, TimeSpan duration, Exception exception)
|
||||
{
|
||||
_healthCheckPublisherError(logger, publisher, duration.TotalMilliseconds, exception);
|
||||
}
|
||||
|
||||
public static void HealthCheckPublisherTimeout(ILogger logger, IHealthCheckPublisher publisher, TimeSpan duration)
|
||||
{
|
||||
_healthCheckPublisherTimeout(logger, publisher, duration.TotalMilliseconds, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for the default service that executes <see cref="IHealthCheckPublisher"/> instances.
|
||||
/// </summary>
|
||||
public sealed class HealthCheckPublisherOptions
|
||||
{
|
||||
private TimeSpan _delay;
|
||||
private TimeSpan _period;
|
||||
|
||||
public HealthCheckPublisherOptions()
|
||||
{
|
||||
_delay = TimeSpan.FromSeconds(5);
|
||||
_period = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the initial delay applied after the application starts before executing
|
||||
/// <see cref="IHealthCheckPublisher"/> instances. The delay is applied once at startup, and does
|
||||
/// not apply to subsequent iterations. The default value is 5 seconds.
|
||||
/// </summary>
|
||||
public TimeSpan Delay
|
||||
{
|
||||
get => _delay;
|
||||
set
|
||||
{
|
||||
if (value == System.Threading.Timeout.InfiniteTimeSpan)
|
||||
{
|
||||
throw new ArgumentException($"The {nameof(Delay)} must not be infinite.", nameof(value));
|
||||
}
|
||||
|
||||
_delay = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the period of <see cref="IHealthCheckPublisher"/> execution. The default value is
|
||||
/// 30 seconds.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The <see cref="Period"/> cannot be set to a value lower than 1 second.
|
||||
/// </remarks>
|
||||
public TimeSpan Period
|
||||
{
|
||||
get => _period;
|
||||
set
|
||||
{
|
||||
if (value < TimeSpan.FromSeconds(1))
|
||||
{
|
||||
throw new ArgumentException($"The {nameof(Period)} must be greater than or equal to one second.", nameof(value));
|
||||
}
|
||||
|
||||
if (value == System.Threading.Timeout.InfiniteTimeSpan)
|
||||
{
|
||||
throw new ArgumentException($"The {nameof(Period)} must not be infinite.", nameof(value));
|
||||
}
|
||||
|
||||
_delay = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a predicate that is used to filter the set of health checks executed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If <see cref="Predicate"/> is <c>null</c>, the health check publisher service will run all
|
||||
/// registered health checks - this is the default behavior. To run a subset of health checks,
|
||||
/// provide a function that filters the set of checks. The predicate will be evaluated each period.
|
||||
/// </remarks>
|
||||
public Func<HealthCheckRegistration, bool> Predicate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timeout for executing the health checks an all <see cref="IHealthCheckPublisher"/>
|
||||
/// instances. Use <see cref="System.Threading.Timeout.InfiniteTimeSpan"/> to execute with no timeout.
|
||||
/// The default value is 30 seconds.
|
||||
/// </summary>
|
||||
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// A service which can be used to check the status of <see cref="IHealthCheck"/> instances
|
||||
/// registered in the application.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The default implementation of <see cref="HealthCheckService"/> is registered in the dependency
|
||||
/// injection container as a singleton service by calling
|
||||
/// <see cref="HealthCheckServiceCollectionExtensions.AddHealthChecks(IServiceCollection)"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The <see cref="IHealthChecksBuilder"/> returned by
|
||||
/// <see cref="HealthCheckServiceCollectionExtensions.AddHealthChecks(IServiceCollection)"/>
|
||||
/// provides a convenience API for registering health checks.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <see cref="IHealthCheck"/> implementations can be registered through extension methods provided by
|
||||
/// <see cref="IHealthChecksBuilder"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public abstract class HealthCheckService
|
||||
{
|
||||
/// <summary>
|
||||
/// Runs all the health checks in the application and returns the aggregated status.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> which can be used to cancel the health checks.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task{T}"/> which will complete when all the health checks have been run,
|
||||
/// yielding a <see cref="HealthReport"/> containing the results.
|
||||
/// </returns>
|
||||
public Task<HealthReport> CheckHealthAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return CheckHealthAsync(predicate: null, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the provided health checks and returns the aggregated status
|
||||
/// </summary>
|
||||
/// <param name="predicate">
|
||||
/// A predicate that can be used to include health checks based on user-defined criteria.
|
||||
/// </param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> which can be used to cancel the health checks.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task{T}"/> which will complete when all the health checks have been run,
|
||||
/// yielding a <see cref="HealthReport"/> containing the results.
|
||||
/// </returns>
|
||||
public abstract Task<HealthReport> CheckHealthAsync(
|
||||
Func<HealthCheckRegistration, bool> predicate,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Options for the default implementation of <see cref="HealthCheckService"/>
|
||||
/// </summary>
|
||||
public sealed class HealthCheckServiceOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the health check registrations.
|
||||
/// </summary>
|
||||
public ICollection<HealthCheckRegistration> Registrations { get; } = new List<HealthCheckRegistration>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Components for performing health checks in .NET applications
|
||||
|
||||
Commonly Used Types:
|
||||
Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService
|
||||
Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder
|
||||
</Description>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PackageTags>diagnostics;healthchecks</PackageTags>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsHostingAbstractionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.NonCapturingTimer.Sources" Version="$(MicrosoftExtensionsNonCapturingTimerSourcesPackageVersion)" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.ValueStopwatch.Sources" Version="$(MicrosoftExtensionsValueStopwatchSourcesPackageVersion)" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.Extensions.Diagnostics.HealthChecks.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"AssemblyIdentity": "Microsoft.Extensions.Diagnostics.HealthChecks, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
|
||||
"Types": [
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue