Reorganize source code in preparation to move into aspnet/AspNetCore

Prior to reorganization, this source code was found in 8893337fb0
This commit is contained in:
Nate McMaster 2018-11-21 13:54:33 -08:00
parent 8893337fb0
commit ed0b421695
No known key found for this signature in database
GPG Key ID: A778D9601BD78810
246 changed files with 257 additions and 10979 deletions

View File

@ -1,17 +0,0 @@
init:
- git config --global core.autocrlf true
branches:
only:
- dev
- /^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

52
.gitattributes vendored
View File

@ -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

View File

@ -1,3 +0,0 @@
THIS ISSUE TRACKER IS CLOSED - please log new issues here: https://github.com/aspnet/Home/issues
For information about this change, see https://github.com/aspnet/Announcements/issues/283

38
.gitignore vendored
View File

@ -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/

View File

@ -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:
- dev
- /^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

View File

@ -1,4 +0,0 @@
Contributing
======
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.

View File

@ -1,380 +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
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
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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D915AA7B-4ADE-4BAC-AF65-1E800D3F3580}
EndGlobalSection
EndGlobal

View File

@ -1,21 +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>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>

View File

@ -1,7 +0,0 @@
<Project>
<PropertyGroup>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">$(MicrosoftNETCoreApp20PackageVersion)</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
</PropertyGroup>
</Project>

View File

@ -1,14 +0,0 @@
Copyright (c) .NET Foundation and Contributors
All rights reserved.
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.

View File

@ -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>

View File

@ -1,7 +0,0 @@
{
"Default": {
"rules": [
"DefaultCompositeRule"
]
}
}

View File

@ -1,11 +0,0 @@
ASP.NET Core Diagnostics
================
AppVeyor: [![AppVeyor](https://ci.appveyor.com/api/projects/status/5224cefq6y78aq21/branch/dev?svg=true)](https://ci.appveyor.com/project/aspnetci/Diagnostics/branch/dev)
Travis: [![Travis](https://travis-ci.org/aspnet/Diagnostics.svg?branch=dev)](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.

View File

@ -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"

View File

@ -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 "$@"

Binary file not shown.

View File

@ -1,52 +0,0 @@
<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<!-- These package versions may be overridden or updated by automation. -->
<PropertyGroup Label="Package Versions: Auto">
<InternalAspNetCoreSdkPackageVersion>2.1.3-rtm-15802</InternalAspNetCoreSdkPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.2</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
<MoqPackageVersion>4.7.49</MoqPackageVersion>
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.0</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemReflectionMetadataPackageVersion>1.6.0</SystemReflectionMetadataPackageVersion>
<XunitPackageVersion>2.3.1</XunitPackageVersion>
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion>
</PropertyGroup>
<!-- This may import a generated file which may override the variables above. -->
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
<!-- These are package versions that should not be overridden or updated by automation. -->
<PropertyGroup Label="Package Versions: Pinned">
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.1</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.1.1</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.1.1</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.1.1</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.2</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.1.1</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>2.1.1</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetCoreWebUtilitiesPackageVersion>2.1.1</MicrosoftAspNetCoreWebUtilitiesPackageVersion>
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>2.1.1</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>2.1.1</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>2.1.1</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>2.1.1</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.1.1</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>2.1.0</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>2.1.1</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>2.1.1</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.1.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.1</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>2.1.1</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>2.1.1</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>2.1.1</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsRazorViewsSourcesPackageVersion>2.1.1</MicrosoftExtensionsRazorViewsSourcesPackageVersion>
<MicrosoftExtensionsStackTraceSourcesPackageVersion>2.1.1</MicrosoftExtensionsStackTraceSourcesPackageVersion>
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>2.1.1</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
</PropertyGroup>
</Project>

View File

@ -1,18 +0,0 @@
<Project>
<Import Project="dependencies.props" />
<ItemGroup>
<ExcludeFromTest Include="$(RepositoryRoot)test\ClassLibraryWithPortablePdbs\*.csproj" />
</ItemGroup>
<PropertyGroup>
<!-- These properties are use by the automation that updates dependencies.props -->
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
<LineupPackageVersion>2.1.0-rc1-*</LineupPackageVersion>
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
</PropertyGroup>
<ItemGroup>
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp20PackageVersion)" />
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp21PackageVersion)" />
</ItemGroup>
</Project>

View File

@ -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>

View File

@ -1,2 +0,0 @@
version:2.1.3-rtm-15802
commithash:a7c08b45b440a7d2058a0aa1eaa3eb6ba811976a

View File

@ -1,4 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json",
"channel": "release/2.1"
}

View File

@ -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"

196
run.ps1
View File

@ -1,196 +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 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 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/dev/tools/korebuild.schema.json",
"channel": "dev",
"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,
[string]$ConfigFile,
[string]$ToolsSourceSuffix,
[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 (!(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 'Expand-Archive' -ErrorAction Ignore) {
# Use built-in commands where possible as they are cross-plat compatible
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-Warning "$ConfigFile could not be read. Its settings will be ignored."
Write-Warning $Error[0]
}
}
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 = 'dev' }
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
Invoke-KoreBuildCommand $Command @Arguments
}
finally {
Remove-Module 'KoreBuild' -ErrorAction Ignore
}

231
run.sh
View File

@ -1,231 +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
repo_path="$DIR"
channel=''
tools_source=''
tools_source_suffix=''
#
# 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 ""
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 [ ! -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
;;
--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
__warn "$config_file is invalid JSON. Its settings will be ignored."
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
__warn "$config_file is invalid JSON. Its settings will be ignored."
fi
else
__warn 'Missing required command: jq or pyton. Could not parse the JSON file. Its settings will be ignored.'
fi
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
fi
[ -z "$channel" ] && channel='dev'
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
get_korebuild
set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file"
invoke_korebuild_command "$command" "$@"

View File

@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -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>");
}
}
}
}

View File

@ -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();
}
}
}

View File

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -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>

View File

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="$(MicrosoftAspNetCoreStaticFilesPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Diagnostics.HealthChecks\Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj" />
</ItemGroup>
</Project>

View File

@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.0;netcoreapp2.1</TargetFrameworks>
</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>

View File

@ -1,9 +0,0 @@
<?xml version="1.0"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
</system.webServer>
</configuration>

View File

@ -1,7 +0,0 @@
<Project>
<Import Project="..\Directory.Build.props" />
<ItemGroup>
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -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; }
}
}

View File

@ -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
};
}
}
}

View File

@ -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>();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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()
{
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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>netstandard2.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>

View File

@ -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;
}
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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; }
}
}

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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; }
}
}

View File

@ -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
}
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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; }
}
}

View File

@ -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
}
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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; }
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -1,32 +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.HealthChecks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
/// <summary>
/// <see cref="IApplicationBuilder"/> extension methods for the <see cref="HealthCheckMiddleware"/>.
/// </summary>
public static class HealthCheckAppBuilderExtensions
{
/// <summary>
/// Adds a middleware that provides a REST API for requesting health check status.
/// </summary>
/// <param name="app">The <see cref="IApplicationBuilder"/>.</param>
/// <param name="path">The path on which to provide the API.</param>
/// <returns>A reference to the <paramref name="app"/> after the operation has completed.</returns>
public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app, PathString path)
{
app = app ?? throw new ArgumentNullException(nameof(app));
return app.UseMiddleware<HealthCheckMiddleware>(Options.Create(new HealthCheckOptions()
{
Path = path
}));
}
}
}

View File

@ -1,79 +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.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
{
public class HealthCheckMiddleware
{
private readonly RequestDelegate _next;
private readonly HealthCheckOptions _healthCheckOptions;
private readonly IHealthCheckService _healthCheckService;
public HealthCheckMiddleware(RequestDelegate next, IOptions<HealthCheckOptions> healthCheckOptions, IHealthCheckService healthCheckService)
{
_next = next;
_healthCheckOptions = healthCheckOptions.Value;
_healthCheckService = healthCheckService;
}
/// <summary>
/// Process an individual request.
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path == _healthCheckOptions.Path)
{
// Get results
var result = await _healthCheckService.CheckHealthAsync(context.RequestAborted);
// Map status to response code
switch (result.Status)
{
case HealthCheckStatus.Failed:
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
break;
case HealthCheckStatus.Unhealthy:
context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
break;
case HealthCheckStatus.Degraded:
// Degraded doesn't mean unhealthy so we return 200, but the content will contain more details
context.Response.StatusCode = StatusCodes.Status200OK;
break;
case HealthCheckStatus.Healthy:
context.Response.StatusCode = StatusCodes.Status200OK;
break;
default:
// This will only happen when we change HealthCheckStatus and we don't update this.
Debug.Fail($"Unrecognized HealthCheckStatus value: {result.Status}");
throw new InvalidOperationException($"Unrecognized HealthCheckStatus value: {result.Status}");
}
// Render results to JSON
var json = new JObject(
new JProperty("status", result.Status.ToString()),
new JProperty("results", new JObject(result.Results.Select(pair =>
new JProperty(pair.Key, new JObject(
new JProperty("status", pair.Value.Status.ToString()),
new JProperty("description", pair.Value.Description),
new JProperty("data", new JObject(pair.Value.Data.Select(p => new JProperty(p.Key, p.Value))))))))));
await context.Response.WriteAsync(json.ToString(Formatting.None));
}
else
{
await _next(context);
}
}
}
}

View File

@ -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 Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
{
/// <summary>
/// Contains options for the <see cref="HealthCheckMiddleware"/>.
/// </summary>
public class HealthCheckOptions
{
/// <summary>
/// Gets or sets the path at which the Health Check results will be available.
/// </summary>
public PathString Path { get; set; }
}
}

View File

@ -1,28 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>ASP.NET Core middleware for returning the results of Health Checks in the application</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>diagnostics;healthchecks</PackageTags>
<Description>ASP.NET Core middleware for returning the results of Health Checks in the application
</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>diagnostics;healthchecks</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Extensions.Diagnostics.HealthChecks\Microsoft.Extensions.Diagnostics.HealthChecks.csproj" />
</ItemGroup>
</Project>

View File

@ -1,115 +0,0 @@
{
"AssemblyIdentity": "Microsoft.AspNetCore.Diagnostics.HealthChecks, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "InvokeAsync",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "healthCheckOptions",
"Type": "Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions>"
},
{
"Name": "healthCheckService",
"Type": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Path",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.Http.PathString",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_Path",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.AspNetCore.Http.PathString"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HealthCheckAppBuilderExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseHealthChecks",
"Parameters": [
{
"Name": "app",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
},
{
"Name": "path",
"Type": "Microsoft.AspNetCore.Http.PathString"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}

View File

@ -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>netstandard2.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>

View File

@ -1,188 +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>();
private string _description;
private IReadOnlyDictionary<string, object> _data;
/// <summary>
/// Gets a <see cref="HealthCheckStatus"/> value indicating the status of the component that was checked.
/// </summary>
public HealthCheckStatus Status { get; }
/// <summary>
/// Gets an <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).
/// </summary>
/// <remarks>
/// This value is expected to be 'null' if <see cref="Status"/> is <see cref="HealthCheckStatus.Healthy"/>.
/// </remarks>
public Exception Exception { get; }
/// <summary>
/// Gets a human-readable description of the status of the component that was checked.
/// </summary>
public string Description => _description ?? string.Empty;
/// <summary>
/// Gets additional key-value pairs describing the health of the component.
/// </summary>
public IReadOnlyDictionary<string, object> Data => _data ?? _emptyReadOnlyDictionary;
/// <summary>
/// Creates a new <see cref="HealthCheckResult"/> with the specified <paramref name="status"/>, <paramref name="exception"/>,
/// <paramref name="description"/>, and <paramref name="data"/>.
/// </summary>
/// <param name="status">A <see cref="HealthCheckStatus"/> value indicating 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="description">A human-readable description of the status of the component that was checked.</param>
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
public HealthCheckResult(HealthCheckStatus status, Exception exception, string description, IReadOnlyDictionary<string, object> data)
{
if (status == HealthCheckStatus.Unknown)
{
throw new ArgumentException($"'{nameof(HealthCheckStatus.Unknown)}' is not a valid value for the 'status' parameter.", nameof(status));
}
Status = status;
Exception = exception;
_description = description;
_data = data;
}
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
public static HealthCheckResult Unhealthy()
=> new HealthCheckResult(HealthCheckStatus.Unhealthy, exception: null, description: string.Empty, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
public static HealthCheckResult Unhealthy(string description)
=> new HealthCheckResult(HealthCheckStatus.Unhealthy, exception: null, description: description, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
public static HealthCheckResult Unhealthy(string description, IReadOnlyDictionary<string, object> data)
=> new HealthCheckResult(HealthCheckStatus.Unhealthy, exception: null, description: description, data: data);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).</param>
public static HealthCheckResult Unhealthy(Exception exception)
=> new HealthCheckResult(HealthCheckStatus.Unhealthy, exception, description: string.Empty, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
/// <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>
public static HealthCheckResult Unhealthy(string description, Exception exception)
=> new HealthCheckResult(HealthCheckStatus.Unhealthy, exception, description, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing an unhealthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing an unhealthy component.</returns>
/// <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 static HealthCheckResult Unhealthy(string description, Exception exception, IReadOnlyDictionary<string, object> data)
=> new HealthCheckResult(HealthCheckStatus.Unhealthy, exception, description, data);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a healthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a healthy component.</returns>
public static HealthCheckResult Healthy()
=> new HealthCheckResult(HealthCheckStatus.Healthy, exception: null, description: string.Empty, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a healthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a healthy component.</returns>
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
public static HealthCheckResult Healthy(string description)
=> new HealthCheckResult(HealthCheckStatus.Healthy, exception: null, description: description, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a healthy component.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a healthy component.</returns>
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
public static HealthCheckResult Healthy(string description, IReadOnlyDictionary<string, object> data)
=> new HealthCheckResult(HealthCheckStatus.Healthy, exception: null, description: description, data: data);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a component in a degraded state.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a component in a degraded state.</returns>
public static HealthCheckResult Degraded()
=> new HealthCheckResult(HealthCheckStatus.Degraded, exception: null, description: string.Empty, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a component in a degraded state.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a component in a degraded state.</returns>
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
public static HealthCheckResult Degraded(string description)
=> new HealthCheckResult(HealthCheckStatus.Degraded, exception: null, description: description, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a component in a degraded state.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a component in a degraded state.</returns>
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
public static HealthCheckResult Degraded(string description, IReadOnlyDictionary<string, object> data)
=> new HealthCheckResult(HealthCheckStatus.Degraded, exception: null, description: description, data: data);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a component in a degraded state.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a component in a degraded state.</returns>
public static HealthCheckResult Degraded(Exception exception)
=> new HealthCheckResult(HealthCheckStatus.Degraded, exception: null, description: string.Empty, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a component in a degraded state.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a component in a degraded state.</returns>
/// <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>
public static HealthCheckResult Degraded(string description, Exception exception)
=> new HealthCheckResult(HealthCheckStatus.Degraded, exception, description, data: null);
/// <summary>
/// Creates a <see cref="HealthCheckResult"/> representing a component in a degraded state.
/// </summary>
/// <returns>A <see cref="HealthCheckResult"/> representing a component in a degraded state.</returns>
/// <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 static HealthCheckResult Degraded(string description, Exception exception, IReadOnlyDictionary<string, object> data)
=> new HealthCheckResult(HealthCheckStatus.Degraded, exception, description, data);
}
}

View File

@ -1,41 +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 status of a health check result.
/// </summary>
/// <remarks>
/// The values of this enum or ordered from least healthy to most healthy. So <see cref="HealthCheckStatus.Degraded"/> is
/// greater than <see cref="HealthCheckStatus.Unhealthy"/> but less than <see cref="HealthCheckStatus.Healthy"/>.
/// </remarks>
public enum HealthCheckStatus
{
/// <summary>
/// This value should not be returned by a health check. It is used to represent an uninitialized value.
/// </summary>
Unknown = 0,
/// <summary>
/// This value should not be returned by a health check. It is used to indicate that an unexpected exception was
/// thrown when running the health check.
/// </summary>
Failed = 1,
/// <summary>
/// Indicates that the health check determined that the component was unhealthy.
/// </summary>
Unhealthy = 2,
/// <summary>
/// Indicates that the health check determined that the component was in a degraded state.
/// </summary>
Degraded = 3,
/// <summary>
/// Indicates that the health check determined that the component was healthy.
/// </summary>
Healthy = 4,
}
}

View File

@ -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.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>
/// Gets the name of the health check, which should indicate the component being checked.
/// </summary>
string Name { get; }
/// <summary>
/// Runs the health check, returning the status of the component being checked.
/// </summary>
/// <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(CancellationToken cancellationToken = default);
}
}

View File

@ -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>

View File

@ -1,377 +0,0 @@
{
"AssemblyIdentity": "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Visibility": "Public",
"Kind": "Struct",
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Status",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckStatus",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Exception",
"Parameters": [],
"ReturnType": "System.Exception",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Description",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Data",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Unhealthy",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Unhealthy",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Unhealthy",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "data",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Unhealthy",
"Parameters": [
{
"Name": "exception",
"Type": "System.Exception"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Unhealthy",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "exception",
"Type": "System.Exception"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Unhealthy",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "exception",
"Type": "System.Exception"
},
{
"Name": "data",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Healthy",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Healthy",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Healthy",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "data",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Degraded",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Degraded",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Degraded",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "data",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Degraded",
"Parameters": [
{
"Name": "exception",
"Type": "System.Exception"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Degraded",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "exception",
"Type": "System.Exception"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Degraded",
"Parameters": [
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "exception",
"Type": "System.Exception"
},
{
"Name": "data",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "status",
"Type": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckStatus"
},
{
"Name": "exception",
"Type": "System.Exception"
},
{
"Name": "description",
"Type": "System.String"
},
{
"Name": "data",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, System.Object>"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckStatus",
"Visibility": "Public",
"Kind": "Enumeration",
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "Unknown",
"Parameters": [],
"GenericParameter": [],
"Literal": "0"
},
{
"Kind": "Field",
"Name": "Failed",
"Parameters": [],
"GenericParameter": [],
"Literal": "1"
},
{
"Kind": "Field",
"Name": "Unhealthy",
"Parameters": [],
"GenericParameter": [],
"Literal": "2"
},
{
"Kind": "Field",
"Name": "Degraded",
"Parameters": [],
"GenericParameter": [],
"Literal": "3"
},
{
"Kind": "Field",
"Name": "Healthy",
"Parameters": [],
"GenericParameter": [],
"Literal": "4"
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Name",
"Parameters": [],
"ReturnType": "System.String",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CheckHealthAsync",
"Parameters": [
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}

View File

@ -1,66 +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.Diagnostics;
namespace Microsoft.Extensions.Diagnostics.HealthChecks
{
/// <summary>
/// Represents the results of multiple health checks.
/// </summary>
public class CompositeHealthCheckResult
{
/// <summary>
/// A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.
/// </summary>
/// <remarks>
/// The keys in this dictionary map to the name of the health check, the values are the <see cref="HealthCheckResult"/>
/// returned when <see cref="IHealthCheck.CheckHealthAsync(System.Threading.CancellationToken)"/> was called for that health check.
/// </remarks>
public IReadOnlyDictionary<string, HealthCheckResult> Results { get; }
/// <summary>
/// Gets a <see cref="HealthCheckStatus"/> representing the aggregate status of all the health checks.
/// </summary>
/// <remarks>
/// This value is determined by taking the "worst" result of all the results. So if any result is <see cref="HealthCheckStatus.Failed"/>,
/// this value is <see cref="HealthCheckStatus.Failed"/>. If no result is <see cref="HealthCheckStatus.Failed"/> but any result is
/// <see cref="HealthCheckStatus.Unhealthy"/>, this value is <see cref="HealthCheckStatus.Unhealthy"/>, etc.
/// </remarks>
public HealthCheckStatus Status { get; }
/// <summary>
/// Create a new <see cref="CompositeHealthCheckResult"/> from the specified results.
/// </summary>
/// <param name="results">A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.</param>
public CompositeHealthCheckResult(IReadOnlyDictionary<string, HealthCheckResult> results)
{
Results = results;
Status = CalculateAggregateStatus(results.Values);
}
private HealthCheckStatus CalculateAggregateStatus(IEnumerable<HealthCheckResult> results)
{
// This is basically a Min() check, but we know the possible range, so we don't need to walk the whole list
var currentValue = HealthCheckStatus.Healthy;
foreach (var result in results)
{
if (currentValue > result.Status)
{
currentValue = result.Status;
}
if (currentValue == HealthCheckStatus.Failed)
{
// Game over, man! Game over!
// (We hit the worst possible status, so there's no need to keep iterating)
return currentValue;
}
}
return currentValue;
}
}
}

View File

@ -1,41 +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>
public class HealthCheck : IHealthCheck
{
private readonly Func<CancellationToken, Task<HealthCheckResult>> _check;
/// <summary>
/// Gets the name of the health check, which should indicate the component being checked.
/// </summary>
public string Name { get; }
/// <summary>
/// Create an instance of <see cref="HealthCheck"/> from the specified <paramref name="name"/> and <paramref name="check"/>.
/// </summary>
/// <param name="name">The name of the health check, which should indicate the component being checked.</param>
/// <param name="check">A delegate which provides the code to execute when the health check is run.</param>
public HealthCheck(string name, Func<CancellationToken, Task<HealthCheckResult>> check)
{
Name = name;
_check = check;
}
/// <summary>
/// Runs the health check, returning the status of the component being checked.
/// </summary>
/// <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(CancellationToken cancellationToken = default) => _check(cancellationToken);
}
}

View File

@ -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();
}
}
}

View File

@ -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;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.Extensions.Diagnostics.HealthChecks
{
/// <summary>
/// Default implementation of <see cref="IHealthCheckService"/>.
/// </summary>
public class HealthCheckService : IHealthCheckService
{
private readonly ILogger<HealthCheckService> _logger;
/// <summary>
/// A <see cref="IReadOnlyDictionary{TKey, T}"/> containing all the health checks registered in the application.
/// </summary>
/// <remarks>
/// The key maps to the <see cref="IHealthCheck.Name"/> property of the health check, and the value is the <see cref="IHealthCheck"/>
/// instance itself.
/// </remarks>
public IReadOnlyDictionary<string, IHealthCheck> Checks { get; }
/// <summary>
/// Constructs a <see cref="HealthCheckService"/> from the provided collection of <see cref="IHealthCheck"/> instances.
/// </summary>
/// <param name="healthChecks">The <see cref="IHealthCheck"/> instances that have been registered in the application.</param>
public HealthCheckService(IEnumerable<IHealthCheck> healthChecks) : this(healthChecks, NullLogger<HealthCheckService>.Instance) { }
/// <summary>
/// Constructs a <see cref="HealthCheckService"/> from the provided collection of <see cref="IHealthCheck"/> instances, and the provided logger.
/// </summary>
/// <param name="healthChecks">The <see cref="IHealthCheck"/> instances that have been registered in the application.</param>
/// <param name="logger">A <see cref="ILogger{T}"/> that can be used to log events that occur during health check operations.</param>
public HealthCheckService(IEnumerable<IHealthCheck> healthChecks, ILogger<HealthCheckService> logger)
{
healthChecks = healthChecks ?? throw new ArgumentNullException(nameof(healthChecks));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
// Scan the list for duplicate names to provide a better error if there are duplicates.
var names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var duplicates = new List<string>();
foreach (var check in healthChecks)
{
if (!names.Add(check.Name))
{
duplicates.Add(check.Name);
}
}
if (duplicates.Count > 0)
{
throw new ArgumentException($"Duplicate health checks were registered with the name(s): {string.Join(", ", duplicates)}", nameof(healthChecks));
}
Checks = healthChecks.ToDictionary(c => c.Name, StringComparer.OrdinalIgnoreCase);
if (_logger.IsEnabled(LogLevel.Debug))
{
foreach (var check in Checks)
{
_logger.LogDebug("Health check '{healthCheckName}' has been registered", check.Key);
}
}
}
/// <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="CompositeHealthCheckResult"/> containing the results.
/// </returns>
public Task<CompositeHealthCheckResult> CheckHealthAsync(CancellationToken cancellationToken = default) =>
CheckHealthAsync(Checks.Values, cancellationToken);
/// <summary>
/// Runs the provided health checks and returns the aggregated status
/// </summary>
/// <param name="checks">The <see cref="IHealthCheck"/> instances to be run.</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="CompositeHealthCheckResult"/> containing the results.
/// </returns>
public async Task<CompositeHealthCheckResult> CheckHealthAsync(IEnumerable<IHealthCheck> checks, CancellationToken cancellationToken = default)
{
var results = new Dictionary<string, HealthCheckResult>(Checks.Count, StringComparer.OrdinalIgnoreCase);
foreach (var check in checks)
{
cancellationToken.ThrowIfCancellationRequested();
// 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(check.Name)))
{
HealthCheckResult result;
try
{
_logger.LogTrace("Running health check: {healthCheckName}", check.Name);
result = await check.CheckHealthAsync(cancellationToken);
_logger.LogTrace("Health check '{healthCheckName}' completed with status '{healthCheckStatus}'", check.Name, result.Status);
}
catch (Exception ex)
{
// We don't log this as an error because a health check failing shouldn't bring down the active task.
_logger.LogError(ex, "Health check '{healthCheckName}' threw an unexpected exception", check.Name);
result = new HealthCheckResult(HealthCheckStatus.Failed, ex, ex.Message, data: null);
}
// This can only happen if the result is default(HealthCheckResult)
if (result.Status == HealthCheckStatus.Unknown)
{
// This is different from the case above. We throw here because a health check is doing something specifically incorrect.
var exception = new InvalidOperationException($"Health check '{check.Name}' returned a result with a status of Unknown");
_logger.LogError(exception, "Health check '{healthCheckName}' returned a result with a status of Unknown", check.Name);
throw exception;
}
results[check.Name] = result;
}
}
return new CompositeHealthCheckResult(results);
}
}
}

View File

@ -1,31 +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;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Provides extension methods for registering <see cref="IHealthCheckService"/> in an <see cref="IServiceCollection"/>.
/// </summary>
public static class HealthCheckServiceCollectionExtensions
{
/// <summary>
/// Adds the <see cref="IHealthCheckService"/> 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="IHealthCheckService"/> 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="IHealthCheckService"/> 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.TryAdd(ServiceDescriptor.Singleton<IHealthCheckService, HealthCheckService>());
return new HealthChecksBuilder(services);
}
}
}

View File

@ -1,17 +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;
namespace Microsoft.Extensions.Diagnostics.HealthChecks
{
internal class HealthChecksBuilder : IHealthChecksBuilder
{
public IServiceCollection Services { get; }
public HealthChecksBuilder(IServiceCollection services)
{
Services = services;
}
}
}

View File

@ -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;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Provides 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"/> to add the check to.</param>
/// <param name="name">The name of the health check, which should indicate the component being checked.</param>
/// <param name="check">A delegate which provides the code to execute when the health check is run.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
public static IHealthChecksBuilder AddCheck(this IHealthChecksBuilder builder, string name, Func<CancellationToken, Task<HealthCheckResult>> check)
{
builder.Services.AddSingleton<IHealthCheck>(services => new HealthCheck(name, check));
return builder;
}
/// <summary>
/// Adds a new health check with the specified name and implementation.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/> to add the check to.</param>
/// <param name="name">The name of the health check, which should indicate the component being checked.</param>
/// <param name="check">A delegate which provides the code to execute when the health check is run.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
public static IHealthChecksBuilder AddCheck(this IHealthChecksBuilder builder, string name, Func<Task<HealthCheckResult>> check) =>
builder.AddCheck(name, _ => check());
}
}

View File

@ -1,46 +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;
using System.Threading;
using System.Threading.Tasks;
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>
public interface IHealthCheckService
{
/// <summary>
/// A <see cref="IReadOnlyDictionary{TKey, T}"/> containing all the health checks registered in the application.
/// </summary>
/// <remarks>
/// The key maps to the <see cref="IHealthCheck.Name"/> property of the health check, and the value is the <see cref="IHealthCheck"/>
/// instance itself.
/// </remarks>
IReadOnlyDictionary<string, IHealthCheck> Checks { get; }
/// <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="CompositeHealthCheckResult"/> containing the results.
/// </returns>
Task<CompositeHealthCheckResult> CheckHealthAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Runs the provided health checks and returns the aggregated status
/// </summary>
/// <param name="checks">The <see cref="IHealthCheck"/> instances to be run.</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="CompositeHealthCheckResult"/> containing the results.
/// </returns>
Task<CompositeHealthCheckResult> CheckHealthAsync(IEnumerable<IHealthCheck> checks,
CancellationToken cancellationToken = default);
}
}

View File

@ -1,22 +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;
namespace Microsoft.Extensions.Diagnostics.HealthChecks
{
/// <summary>
/// A builder used to collect instances of <see cref="IHealthCheck"/> and register them on an <see cref="IServiceCollection"/>.
/// </summary>
/// <remarks>
/// This type wraps an <see cref="IServiceCollection"/> and provides a place for health check components to attach extension
/// methods for registering themselves in the <see cref="IServiceCollection"/>.
/// </remarks>
public interface IHealthChecksBuilder
{
/// <summary>
/// Gets the <see cref="IServiceCollection"/> into which <see cref="IHealthCheck"/> instances should be registered.
/// </summary>
IServiceCollection Services { get; }
}
}

View File

@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Components for performing health checks in .NET applications
Commonly Used Types:
Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService
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.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions\Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.csproj" />
</ItemGroup>
</Project>

View File

@ -1,334 +0,0 @@
{
"AssemblyIdentity": "Microsoft.Extensions.Diagnostics.HealthChecks, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.Extensions.DependencyInjection.HealthChecksBuilderAddCheckExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "AddCheck",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder"
},
{
"Name": "name",
"Type": "System.String"
},
{
"Name": "check",
"Type": "System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "AddCheck",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder"
},
{
"Name": "name",
"Type": "System.String"
},
{
"Name": "check",
"Type": "System.Func<System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>>"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.DependencyInjection.HealthCheckServiceCollectionExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "AddHealthChecks",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
}
],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.CompositeHealthCheckResult",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Results",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IReadOnlyDictionary<System.String, Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Status",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckStatus",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "results",
"Type": "System.Collections.Generic.IReadOnlyDictionary<System.String, Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheck",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [
"Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck"
],
"Members": [
{
"Kind": "Method",
"Name": "get_Name",
"Parameters": [],
"ReturnType": "System.String",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CheckHealthAsync",
"Parameters": [
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "name",
"Type": "System.String"
},
{
"Name": "check",
"Type": "System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>>"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [
"Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService"
],
"Members": [
{
"Kind": "Method",
"Name": "get_Checks",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IReadOnlyDictionary<System.String, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck>",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CheckHealthAsync",
"Parameters": [
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.CompositeHealthCheckResult>",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CheckHealthAsync",
"Parameters": [
{
"Name": "checks",
"Type": "System.Collections.Generic.IEnumerable<Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck>"
},
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.CompositeHealthCheckResult>",
"Sealed": true,
"Virtual": true,
"ImplementedInterface": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "healthChecks",
"Type": "System.Collections.Generic.IEnumerable<Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck>"
}
],
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "healthChecks",
"Type": "System.Collections.Generic.IEnumerable<Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck>"
},
{
"Name": "logger",
"Type": "Microsoft.Extensions.Logging.ILogger<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService>"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthChecksBuilder",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Services",
"Parameters": [],
"ReturnType": "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheckService",
"Visibility": "Public",
"Kind": "Interface",
"Abstract": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Checks",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IReadOnlyDictionary<System.String, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck>",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CheckHealthAsync",
"Parameters": [
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.CompositeHealthCheckResult>",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "CheckHealthAsync",
"Parameters": [
{
"Name": "checks",
"Type": "System.Collections.Generic.IEnumerable<Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck>"
},
{
"Name": "cancellationToken",
"Type": "System.Threading.CancellationToken",
"DefaultValue": "default(System.Threading.CancellationToken)"
}
],
"ReturnType": "System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.CompositeHealthCheckResult>",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}

Some files were not shown because too many files have changed in this diff Show More