Пример #1
0
        private void HandleServerTiming(HttpContext context, IServerTiming serverTiming)
        {
            context.Response.OnStarting(() => {
                if (serverTiming.Metrics.Count > 0)
                {
                    context.Response.SetServerTiming(new ServerTimingHeaderValue(serverTiming.Metrics));
                }

                return(_completedTask);
            });
        }
 private async Task HandleServerTimingAsync(HttpContext context, IServerTiming serverTiming)
 {
     if (context.Request.AllowsTrailers() && context.Response.SupportsTrailers())
     {
         await HandleServerTimingAsTrailerHeaderAsync(context, serverTiming);
     }
     else
     {
         await HandleServerTimingAsResponseHeaderAsync(context, serverTiming);
     }
 }
        public WebCamGallery(IConfiguration configuration, IServerTiming serverTiming)
        {
            Watch = new Stopwatch();
            Watch.Start();

            _imageDirectory = configuration["ImageDirectory"];
            _serverTiming   = serverTiming;

            BaseWebCamURL = configuration["BaseWebCamURL"];
            LiveWebCamURL = configuration["LiveWebCamURL"];
        }
 /// <summary>
 /// Time an async task.
 /// </summary>
 /// <typeparam name="T">Type of the task.</typeparam>
 /// <param name="task">The <see cref="Task"/> to time.</param>
 /// <param name="serverTiming">The <see cref="IServerTiming"/> to add metric to.</param>
 /// <param name="metricName">Optional, metric name, if passed will override any caller name.</param>
 /// <param name="functionName">Optional, populated compile-time with the name of the calling function.</param>
 /// <param name="filePath">Optional, populated compile-time with the path to the calling file.</param>
 /// <param name="lineNumber">Optional, populated compile-time with line number in the calling file.</param>
 /// <returns></returns>
 public static async Task <T> TimeTask <T>(this IServerTiming serverTiming,
                                           Task <T> task,
                                           string metricName = null,
                                           [CallerMemberName] string functionName = null,
                                           [CallerFilePath] string filePath       = null,
                                           [CallerLineNumber] int lineNumber      = 0)
 {
     using (serverTiming.TimeAction(metricName, functionName, filePath, lineNumber))
     {
         return(await task);
     }
 }
        /// <summary>
        /// Called on GET.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="serverTiming">The server timing.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        public IActionResult OnGet([FromServices] IConfiguration configuration, [FromServices] IServerTiming serverTiming, string fileName)
        {
            var watch = new Stopwatch();

            watch.Start();

            string imageDirectory = configuration["ImageDirectory"];

            if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(imageDirectory))
            {
                serverTiming.Metrics.Add(new Lib.AspNetCore.ServerTiming.Http.Headers.ServerTimingMetric("GET", watch.ElapsedMilliseconds, "error"));
                return(NotFound("No image directory present"));
            }

            string path = Path.Combine(imageDirectory, fileName);

            if (System.IO.File.Exists(path))
            {
                if (Path.GetDirectoryName(path) == imageDirectory)
                {
                    var            fi     = new FileInfo(path);
                    var            length = fi.Length;
                    DateTimeOffset last   = fi.LastWriteTime;
                    // Truncate to the second.
                    var lastModified = new DateTimeOffset(last.Year, last.Month, last.Day, last.Hour, last.Minute, last.Second, last.Offset).ToUniversalTime();

                    long etagHash = lastModified.ToFileTime() ^ length;
                    var  etag_str = $"\"{Convert.ToString(etagHash, 16)}\"";

                    if (Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out StringValues incomingEtag) &&
                        string.Compare(incomingEtag[0], etag_str) == 0)
                    {
                        Response.Clear();
                        Response.StatusCode = (int)HttpStatusCode.NotModified;
                        serverTiming.Metrics.Add(new Lib.AspNetCore.ServerTiming.Http.Headers.ServerTimingMetric("GET", watch.ElapsedMilliseconds, "NotModified GET"));

                        return(new StatusCodeResult((int)HttpStatusCode.NotModified));
                    }
                    var etag = new EntityTagHeaderValue(etag_str);

                    //var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                    PhysicalFileResult pfr = base.PhysicalFile(path, MediaTypeNames.Image.Jpeg);
                    pfr.EntityTag = etag;
                    //pfr.LastModified = lastModified;
                    serverTiming.Metrics.Add(new Lib.AspNetCore.ServerTiming.Http.Headers.ServerTimingMetric("GET", watch.ElapsedMilliseconds, "full file GET"));

                    return(pfr);
                }
            }
            serverTiming.Metrics.Add(new Lib.AspNetCore.ServerTiming.Http.Headers.ServerTimingMetric("GET", watch.ElapsedMilliseconds, "not found GET"));
            return(NotFound());
        }
Пример #6
0
        private void HandleServerTiming(HttpContext context)
        {
            context.Response.OnStarting(() => {
                IServerTiming serverTiming = context.RequestServices.GetRequiredService <IServerTiming>();

                if (serverTiming.Metrics.Count > 0)
                {
                    context.Response.SetServerTiming(new ServerTimingHeaderValue(serverTiming.Metrics));
                }

                return(_completedTask);
            });
        }
Пример #7
0
        public WebCamGallery(IConfiguration configuration, IServerTiming serverTiming) : base(configuration)
        {
            Watch = new Stopwatch();
            Watch.Start();

            _imageDirectory = configuration["ImageDirectory"];
            _serverTiming   = serverTiming;

            BaseWebCamURL = configuration["BaseWebCamURL"];
            LiveWebCamURL = configuration["LiveWebCamURL"];

            YouTubePlaylistId = configuration["YouTubeAPI:playlistId"];
        }
Пример #8
0
        public void Configure(IApplicationBuilder app)
        {
            app.UseServerTiming()
            .Run(async(context) =>
            {
                IServerTiming serverTiming = context.RequestServices.GetService <IServerTiming>();

                await Task.Delay(DELAY_SERVER_TIMING_METRIC_VALUE);

                serverTiming.Metrics.Add(new ServerTimingMetric(DELAY_SERVER_TIMING_METRIC_NAME, DELAY_SERVER_TIMING_METRIC_VALUE, DELAY_SERVER_TIMING_METRIC_DESCRIPTION));

                await context.Response.WriteAsync(RESPONSE_BODY);
            });
        }
        /// <summary>
        /// Process an individual request.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="serverTiming">The instance of <see cref="IServerTiming"/> for current requet.</param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public Task Invoke(HttpContext context, IServerTiming serverTiming)
        {
            if (serverTiming is null)
            {
                throw new ArgumentNullException(nameof(serverTiming));
            }

            if (_timingAllowOriginHeaderValue != null)
            {
                context.Response.SetResponseHeader(HeaderNames.TimingAllowOrigin, _timingAllowOriginHeaderValue);
            }

            return(HandleServerTimingAsync(context, serverTiming));
        }
        /// <summary>
        /// Time a block of code.
        /// </summary>
        /// <param name="serverTiming">The <see cref="IServerTiming"/> to add metric to.</param>
        /// <param name="metricName">Optional, metric name, if passed will override any caller name.</param>
        /// <param name="functionName">Optional, populated compile-time with the name of the calling function.</param>
        /// <param name="filePath">Optional, populated compile-time with the path to the calling file.</param>
        /// <param name="lineNumber">Optional, populated compile-time with line number in the calling file.</param>
        public static IDisposable TimeAction(this IServerTiming serverTiming,
                                             string metricName = null,
                                             [CallerMemberName] string functionName = null,
                                             [CallerFilePath] string filePath       = null,
                                             [CallerLineNumber] int lineNumber      = 0)
        {
            if (serverTiming is null)
            {
                return(null);
            }

            string caller = metricName ?? FormatCallerName(functionName, filePath, lineNumber);

            return(new ServerTimingInstance(serverTiming, caller));
        }
        private Task HandleServerTimingAsResponseHeaderAsync(HttpContext context, IServerTiming serverTiming)
        {
            context.Response.OnStarting(() => {
                if (serverTiming.Metrics.Count > 0)
                {
                    context.Response.SetServerTiming(new ServerTimingHeaderValue(serverTiming.Metrics));
                }

                return(_completedTask);
            });

            serverTiming.SetServerTimingDeliveryMode(ServerTimingDeliveryMode.ResponseHeader);

            return(_next(context));
        }
        /// <summary>
        /// Add a timed metric to the timing, if present.
        /// </summary>
        /// <param name="serverTiming">The <see cref="IServerTiming"/> to add metric to.</param>
        /// <param name="duration">The duration to log in ms.</param>
        /// <param name="metricName">The name of the metric to log.</param>
        /// <param name="functionName">Optional, populated compile-time with the name of the calling function</param>
        /// <param name="filePath">Optional, populated compile-time with the path to the calling file</param>
        /// <param name="lineNumber">Optional, populated compile-time with line number in the calling file</param>
        public static void AddMetric(this IServerTiming serverTiming, decimal duration,
                                     string metricName = null,
                                     [CallerMemberName] string functionName = null,
                                     [CallerFilePath] string filePath       = null,
                                     [CallerLineNumber] int lineNumber      = 0)
        {
            if (serverTiming is null)
            {
                return;
            }

            ServerTimingMetric metric = new ServerTimingMetric(metricName ?? FormatCallerName(functionName, filePath, lineNumber), duration);

            serverTiming.Metrics.Add(metric);
        }
        /// <summary>
        /// Called on live image GET.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="serverTiming">The server timing.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        public async Task <IActionResult> OnGetLiveAsync([FromServices] IServerTiming serverTiming,
                                                         [FromServices] IMjpgStreamerHttpClient client)
        {
            var watch = new Stopwatch();

            watch.Start();

            try
            {
                var file = await client.GetLiveImage(HttpContext.RequestAborted);

                return(file);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                serverTiming.Metrics.Add(new Lib.AspNetCore.ServerTiming.Http.Headers.ServerTimingMetric("GET", watch.ElapsedMilliseconds, "live image get"));
            }
        }
Пример #14
0
        internal async Task OnResponseCompleted(HttpContext httpContext, IServerTiming serverTiming, IReadOnlyList <IServerTimingCallback> callbacks)
        {
            var metrics     = serverTiming.GetMetrics();
            var timingEvent = new ServerTimingEvent(httpContext, metrics);

            var tasks = new Task[callbacks.Count];

            for (var i = 0; i < callbacks.Count; i++)
            {
                tasks[i] = callbacks[i].OnServerTiming(timingEvent);
            }

            var aggregationTask = Task.WhenAll(tasks);

            try
            {
                await aggregationTask;
            }
            // ReSharper disable once EmptyGeneralCatchClause
            catch (Exception)
            {
                // AggregateException will be available below with exceptions from all tasks.
            }

            if (aggregationTask.Exception == null)
            {
                return;
            }

            var innerExceptions = aggregationTask.Exception.InnerExceptions;

            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < innerExceptions.Count; i++)
            {
                _logger.LogError(innerExceptions[i], "Exception was thrown invoking Server Timing callback");
            }
        }
Пример #15
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseServerTiming()
            .UseRouting()
            .UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            })
            .Run(async(context) =>
            {
                IServerTiming serverTiming = context.RequestServices.GetRequiredService <IServerTiming>();
                serverTiming.Metrics.Add(new ServerTimingMetric("cache", 300, "Cache"));
                serverTiming.Metrics.Add(new ServerTimingMetric("sql", 900, "Sql Server"));
                serverTiming.Metrics.Add(new ServerTimingMetric("fs", 600, "FileSystem"));
                serverTiming.Metrics.Add(new ServerTimingMetric("cpu", 1230, "Total CPU"));

                await context.Response.WriteAsync("-- Demo.AspNetCore.ServerTiming --");
            });
        }
 private Task HandleServerTimingAsync(HttpContext context, IServerTiming serverTiming)
 {
     return(HandleServerTimingAsResponseHeaderAsync(context, serverTiming));
 }
        private async Task HandleServerTimingAsTrailerHeaderAsync(HttpContext context, IServerTiming serverTiming)
        {
            context.Response.DeclareTrailer(HeaderNames.ServerTiming);

            serverTiming.SetServerTimingDeliveryMode(ServerTimingDeliveryMode.Trailer);

            await _next(context);

            RunServerTimingMetricFilters(serverTiming, context);
            if (serverTiming.Metrics.Any())
            {
                context.Response.SetServerTimingTrailer(new ServerTimingHeaderValue(serverTiming.Metrics));
            }
        }
Пример #18
0
 public SampleController(IServerTiming serverTiming) => _serverTiming = serverTiming;
Пример #19
0
        internal Task OnResponseStarting(HttpContext httpContext, IManualMetric totalMetric, IServerTiming serverTiming, RequestTimingOptions requestOptions)
        {
            totalMetric.Stop();

            var metrics = serverTiming.GetMetrics();

            if (_options.ValidateMetrics && httpContext.Response.StatusCode != 500)
            {
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < metrics.Count; i++)
                {
                    if (metrics[i] is IValidatableMetric validatableMetric)
                    {
                        if (!validatableMetric.Validate(out var message))
                        {
                            _logger.LogWarning(message);
                        }
                    }
                }
            }

            if (!requestOptions.WriteHeader)
            {
                return(Task.CompletedTask);
            }

            if (!requestOptions.IncludeCustomMetrics)
            {
                metrics = new[] { (IMetric)totalMetric }
            }
            ;

            _headerWriter.WriteHeaders(httpContext.Response.Headers, requestOptions.IncludeDescriptions, metrics);

            return(Task.CompletedTask);
        }