Skip to content
This repository was archived by the owner on Nov 22, 2018. It is now read-only.

Commit 37f19b4

Browse files
author
Victor Hurdugaci
committed
Improve logging and add more messages
1 parent 4310fa1 commit 37f19b4

File tree

4 files changed

+200
-31
lines changed

4 files changed

+200
-31
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.Primitives;
7+
8+
namespace Microsoft.AspNet.StaticFiles
9+
{
10+
/// <summary>
11+
/// Defines *all* the logger messages produced by static files
12+
/// </summary>
13+
internal static class LoggerExtensions
14+
{
15+
private static Action<ILogger, string, Exception> _logMethodNotSupported;
16+
private static Action<ILogger, string, string, Exception> _logFileServed;
17+
private static Action<ILogger, string, Exception> _logPathMismatch;
18+
private static Action<ILogger, string, Exception> _logFileTypeNotSupported;
19+
private static Action<ILogger, string, Exception> _logFileNotFound;
20+
private static Action<ILogger, string, Exception> _logPathNotModified;
21+
private static Action<ILogger, string, Exception> _logPreconditionFailed;
22+
private static Action<ILogger, int, string, Exception> _logHandled;
23+
private static Action<ILogger, string, Exception> _logRangeNotSatisfiable;
24+
private static Action<ILogger, StringValues, string, Exception> _logSendingFileRange;
25+
private static Action<ILogger, StringValues, string, Exception> _logCopyingFileRange;
26+
private static Action<ILogger, long, string, string, Exception> _logCopyingBytesToResponse;
27+
private static Action<ILogger, string, Exception> _logMultipleFileRanges;
28+
29+
static LoggerExtensions()
30+
{
31+
_logMethodNotSupported = LoggerMessage.Define<string>(
32+
logLevel: LogLevel.Verbose,
33+
eventId: 1,
34+
formatString: "{Method} requests are not supported");
35+
_logFileServed = LoggerMessage.Define<string, string>(
36+
logLevel: LogLevel.Information,
37+
eventId: 2,
38+
formatString: "Sending file. Request path: '{VirtualPath}'. Physical path: '{PhysicalPath}'");
39+
_logPathMismatch = LoggerMessage.Define<string>(
40+
logLevel: LogLevel.Verbose,
41+
eventId: 3,
42+
formatString: "The request path {Path} does not match the path filter");
43+
_logFileTypeNotSupported = LoggerMessage.Define<string>(
44+
logLevel: LogLevel.Verbose,
45+
eventId: 4,
46+
formatString: "The request path {Path} does not match a supported file type");
47+
_logFileNotFound = LoggerMessage.Define<string>(
48+
logLevel: LogLevel.Verbose,
49+
eventId: 5,
50+
formatString: "The request path {Path} does not match an existing file");
51+
_logPathNotModified = LoggerMessage.Define<string>(
52+
logLevel: LogLevel.Information,
53+
eventId: 6,
54+
formatString: "The file {Path} was not modified");
55+
_logPreconditionFailed = LoggerMessage.Define<string>(
56+
logLevel: LogLevel.Information,
57+
eventId: 7,
58+
formatString: "Precondition for {Path} failed");
59+
_logHandled = LoggerMessage.Define<int, string>(
60+
logLevel: LogLevel.Verbose,
61+
eventId: 8,
62+
formatString: "Handled. Status code: {StatusCode} File: {Path}");
63+
_logRangeNotSatisfiable = LoggerMessage.Define<string>(
64+
logLevel: LogLevel.Warning,
65+
eventId: 9,
66+
formatString: "Range not satisfiable for {Path}");
67+
_logSendingFileRange = LoggerMessage.Define<StringValues, string>(
68+
logLevel: LogLevel.Information,
69+
eventId: 10,
70+
formatString: "Sending {Range} of file {Path}");
71+
_logCopyingFileRange = LoggerMessage.Define<StringValues, string>(
72+
logLevel: LogLevel.Verbose,
73+
eventId: 11,
74+
formatString: "Copying {Range} of file {Path} to the response body");
75+
_logCopyingBytesToResponse = LoggerMessage.Define<long, string, string>(
76+
logLevel: LogLevel.Verbose,
77+
eventId: 12,
78+
formatString: "Copying bytes {Start}-{End} of file {Path} to response body");
79+
_logMultipleFileRanges = LoggerMessage.Define<string>(
80+
logLevel: LogLevel.Warning,
81+
eventId: 13,
82+
formatString: "Multiple ranges are not allowed: '{Ranges}'");
83+
}
84+
85+
public static void LogRequestMethodNotSupported(this ILogger logger, string method)
86+
{
87+
_logMethodNotSupported(logger, method, null);
88+
}
89+
90+
public static void LogFileServed(this ILogger logger, string virtualPath, string physicalPath)
91+
{
92+
if (string.IsNullOrEmpty(physicalPath))
93+
{
94+
physicalPath = "N/A";
95+
}
96+
_logFileServed(logger, virtualPath, physicalPath, null);
97+
}
98+
99+
public static void LogPathMismatch(this ILogger logger, string path)
100+
{
101+
_logPathMismatch(logger, path, null);
102+
}
103+
104+
public static void LogFileTypeNotSupported(this ILogger logger, string path)
105+
{
106+
_logFileTypeNotSupported(logger, path, null);
107+
}
108+
109+
public static void LogFileNotFound(this ILogger logger, string path)
110+
{
111+
_logFileNotFound(logger, path, null);
112+
}
113+
114+
public static void LogPathNotModified(this ILogger logger, string path)
115+
{
116+
_logPathNotModified(logger, path, null);
117+
}
118+
119+
public static void LogPreconditionFailed(this ILogger logger, string path)
120+
{
121+
_logPreconditionFailed(logger, path, null);
122+
}
123+
124+
public static void LogHandled(this ILogger logger, int statusCode, string path)
125+
{
126+
_logHandled(logger, statusCode, path, null);
127+
}
128+
129+
public static void LogRangeNotSatisfiable(this ILogger logger, string path)
130+
{
131+
_logRangeNotSatisfiable(logger, path, null);
132+
}
133+
134+
public static void LogSendingFileRange(this ILogger logger, StringValues range, string path)
135+
{
136+
_logSendingFileRange(logger, range, path, null);
137+
}
138+
139+
public static void LogCopyingFileRange(this ILogger logger, StringValues range, string path)
140+
{
141+
_logCopyingFileRange(logger, range, path, null);
142+
}
143+
144+
public static void LogCopyingBytesToResponse(this ILogger logger, long start, long? end, string path)
145+
{
146+
_logCopyingBytesToResponse(
147+
logger,
148+
start,
149+
end != null ? end.ToString() : "*",
150+
path,
151+
null);
152+
}
153+
154+
public static void LogMultipleFileRanges(this ILogger logger, string range)
155+
{
156+
_logMultipleFileRanges(logger, range, null);
157+
}
158+
}
159+
}

src/Microsoft.AspNet.StaticFiles/SendFileMiddleware.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ public async Task SendFileAsync(string fileName, long offset, long? length, Canc
103103
try
104104
{
105105
fileStream.Seek(offset, SeekOrigin.Begin);
106-
if (_logger.IsEnabled(LogLevel.Verbose))
107-
{
108-
_logger.LogVerbose(string.Format("Copying bytes {0}-{1} of file {2} to response body", offset, length != null ? (offset + length).ToString() : "*", fileName));
109-
}
106+
107+
_logger.LogCopyingBytesToResponse(
108+
start: offset,
109+
end: length != null ? (offset + length) : null,
110+
path: fileName);
110111
await StreamCopyOperation.CopyToAsync(fileStream, _output, length, cancel);
111112
}
112113
finally

src/Microsoft.AspNet.StaticFiles/StaticFileContext.cs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ public string SubPath
9595
get { return _subPath.Value; }
9696
}
9797

98+
public string PhysicalPath
99+
{
100+
get { return _fileInfo?.PhysicalPath; }
101+
}
102+
98103
public bool ValidateMethod()
99104
{
100105
_method = _request.Method;
@@ -226,7 +231,7 @@ private void ComputeRange()
226231
// The spec allows for multiple ranges but we choose not to support them because the client may request
227232
// very strange ranges (e.g. each byte separately, overlapping ranges, etc.) that could negatively
228233
// impact the server. Ignore the header and serve the response normally.
229-
_logger.LogWarning("Multiple ranges are not allowed: '{0}'", rangeHeader.ToString());
234+
_logger.LogMultipleFileRanges(rangeHeader.ToString());
230235
return;
231236
}
232237

@@ -312,10 +317,7 @@ public Task SendStatusAsync(int statusCode)
312317
{
313318
ApplyResponseHeaders(statusCode);
314319

315-
if (_logger.IsEnabled(LogLevel.Verbose))
316-
{
317-
_logger.LogVerbose(string.Format("Handled. Status code: {0} File: {1}", statusCode, SubPath));
318-
}
320+
_logger.LogHandled(statusCode, SubPath);
319321
return Constants.CompletedTask;
320322
}
321323

@@ -358,7 +360,8 @@ internal async Task SendRangeAsync()
358360
// the current length of the selected resource. e.g. */length
359361
_responseHeaders.ContentRange = new ContentRangeHeaderValue(_length);
360362
ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable);
361-
_logger.LogWarning("Range not satisfiable for {0}", SubPath);
363+
364+
_logger.LogRangeNotSatisfiable(SubPath);
362365
return;
363366
}
364367

@@ -374,10 +377,7 @@ internal async Task SendRangeAsync()
374377
var sendFile = _context.Features.Get<IHttpSendFileFeature>();
375378
if (sendFile != null && !string.IsNullOrEmpty(physicalPath))
376379
{
377-
if (_logger.IsEnabled(LogLevel.Verbose))
378-
{
379-
_logger.LogVerbose(string.Format("Sending {0} of file {1}", _response.Headers[HeaderNames.ContentRange], physicalPath));
380-
}
380+
_logger.LogSendingFileRange(_response.Headers[HeaderNames.ContentRange], physicalPath);
381381
await sendFile.SendFileAsync(physicalPath, start, length, _context.RequestAborted);
382382
return;
383383
}
@@ -386,10 +386,7 @@ internal async Task SendRangeAsync()
386386
try
387387
{
388388
readStream.Seek(start, SeekOrigin.Begin); // TODO: What if !CanSeek?
389-
if (_logger.IsEnabled(LogLevel.Verbose))
390-
{
391-
_logger.LogVerbose(string.Format("Copying {0} of file {1} to the response body", _response.Headers[HeaderNames.ContentRange], SubPath));
392-
}
389+
_logger.LogCopyingFileRange(_response.Headers[HeaderNames.ContentRange], SubPath);
393390
await StreamCopyOperation.CopyToAsync(readStream, _response.Body, length, _context.RequestAborted);
394391
}
395392
finally

src/Microsoft.AspNet.StaticFiles/StaticFileMiddleware.cs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Diagnostics;
56
using System.Threading.Tasks;
67
using Microsoft.AspNet.Builder;
78
using Microsoft.AspNet.Hosting;
@@ -68,11 +69,26 @@ public StaticFileMiddleware(RequestDelegate next, IHostingEnvironment hostingEnv
6869
public Task Invoke(HttpContext context)
6970
{
7071
var fileContext = new StaticFileContext(context, _options, _matchUrl, _logger);
71-
if (fileContext.ValidateMethod()
72-
&& fileContext.ValidatePath()
73-
&& fileContext.LookupContentType()
74-
&& fileContext.LookupFileInfo())
72+
73+
if (!fileContext.ValidateMethod())
7574
{
75+
_logger.LogRequestMethodNotSupported(context.Request.Method);
76+
}
77+
else if (!fileContext.ValidatePath())
78+
{
79+
_logger.LogPathMismatch(fileContext.SubPath);
80+
}
81+
else if (!fileContext.LookupContentType())
82+
{
83+
_logger.LogFileTypeNotSupported(fileContext.SubPath);
84+
}
85+
else if (!fileContext.LookupFileInfo())
86+
{
87+
_logger.LogFileNotFound(fileContext.SubPath);
88+
}
89+
else
90+
{
91+
// If we get here, we can try to serve the file
7692
fileContext.ComprehendRequestHeaders();
7793

7894
switch (fileContext.GetPreconditionState())
@@ -87,25 +103,21 @@ public Task Invoke(HttpContext context)
87103
{
88104
return fileContext.SendRangeAsync();
89105
}
90-
if (_logger.IsEnabled(LogLevel.Verbose))
91-
{
92-
_logger.LogVerbose(string.Format("Copying file {0} to the response body", fileContext.SubPath));
93-
}
106+
107+
_logger.LogFileServed(fileContext.SubPath, fileContext.PhysicalPath);
94108
return fileContext.SendAsync();
95109

96110
case StaticFileContext.PreconditionState.NotModified:
97-
if (_logger.IsEnabled(LogLevel.Verbose))
98-
{
99-
_logger.LogVerbose(string.Format("{0} not modified", fileContext.SubPath));
100-
}
111+
_logger.LogPathNotModified(fileContext.SubPath);
101112
return fileContext.SendStatusAsync(Constants.Status304NotModified);
102113

103114
case StaticFileContext.PreconditionState.PreconditionFailed:
115+
_logger.LogPreconditionFailed(fileContext.SubPath);
104116
return fileContext.SendStatusAsync(Constants.Status412PreconditionFailed);
105117

106118
default:
107119
var exception = new NotImplementedException(fileContext.GetPreconditionState().ToString());
108-
_logger.LogError("No precondition state specified", exception);
120+
Debug.Fail(exception.ToString());
109121
throw exception;
110122
}
111123
}

0 commit comments

Comments
 (0)