private static bool IsMatch(RequestTrace requestTrace, string httpMethod, string path) { string baseUri = EncodedPathFromUri(requestTrace.Uri); return((httpMethod == null || requestTrace.Method.Equals(httpMethod, StringComparison.OrdinalIgnoreCase)) && (path == null || baseUri.Equals(path, StringComparison.OrdinalIgnoreCase))); }
/// <summary> /// Executes trace of response using provided data /// </summary> /// <param name="request">Related request</param> /// <param name="bodyType">Result type</param> /// <param name="bodyContent">Body content</param> /// <param name="bodyLenght">Body length</param> /// <param name="exception">Raised exception</param> /// <returns>Returns response trace</returns> public static ResponseTrace GenerateResponse(RequestTrace request, string bodyContent, string bodyType, int?bodyLenght, Exception exception) { //Validazione argomenti if (request == null) { throw new ArgumentNullException(nameof(request)); } //Predispongo il messaggio di errore string exceptionMessage = null; string exceptionStackTrace = null; //Se ho un'eccezione if (exception != null) { //Recupero messaggio e eccezion exceptionMessage = exception.Message; exceptionStackTrace = exception.ToString(); //Tento il casting a "ReflectionTypeLoadException" ReflectionTypeLoadException reflection = exception as ReflectionTypeLoadException; //Se il cast ha avuto successo if (reflection != null) { //Scorro tutte le eccezioni di caricamento e le accodo foreach (var current in reflection.LoaderExceptions) { //Accodo messaggio e stacktrace exceptionMessage = $"{exceptionMessage}{Environment.NewLine}=>{current.Message}"; exceptionStackTrace = $"{exceptionStackTrace}{Environment.NewLine}=>{current}"; } } } //Inizializzo la response return(new ResponseTrace { //Applico la data di creazione e la durata CreationDate = DateTime.Now, Duration = DateTime.Now.Subtract(request.CreationDate), //Inserisco la request relativa e il tipo di risultato Request = request, //Traccio il body BodyType = bodyType, BodyContent = bodyContent, BodyLenght = bodyLenght, //Inserisco l'evenentuale errore generato Error = new ErrorTrace { HasError = exception != null, Message = exceptionMessage, StackTrace = exceptionStackTrace, } }); }
public void Request(RequestTrace requestTrace) { var requestTelemetry = new RequestTelemetry(requestTrace.Route, requestTrace.StartTime, requestTrace.Duration, requestTrace.ResponseCode, requestTrace.Successful); AddAppName(requestTelemetry.Properties); _telemetryClient?.TrackRequest(requestTelemetry); }
/// <summary> /// Remove an <paramref name="item"/> from the collection along with any /// of its key aliases. /// </summary> /// <param name="item">Item to be removed</param> public void Remove(RequestTrace item) { while (item.Id.Count > 0) { var key = item.Id.Pop(); _dictionary.Remove(key); } }
/// <summary> /// Trace request of action /// </summary> /// <param name="request">Request trace</param> protected virtual void TraceRequest(RequestTrace request) { //Eseguo la stringhificazione della request string value = TraceUtils.StringifyRequest(request); //Di base eseguo il tracciamento sul tracer impostato Debug.Write($"[{GetType().Name}] REQUEST: {value}"); }
/// <summary> /// Convert to string specified request trace /// </summary> /// <param name="request">Request trace</param> /// <returns>Returns string representing object</returns> public static string StringifyRequest(RequestTrace request) { //Arguments validation if (request == null) { throw new ArgumentNullException(nameof(request)); } //List of parameters var cleanedParams = new Dictionary <string, object>(); //Scorro tutti gli elementi presenti nelle action params foreach (var currentParam in request.ActionParameters) { //Predispongo la key e i valori string cleanKey = currentParam.Key; object cleanValue; //Poichè l'elemento è un object che potrebbe non essere //serializzabile (es. "HttpPostedFileWrapper") eseguo la //serializzazione di ogni singolo valore, impostando un //placeholder nel caso in cui la serializzazione fallisca try { //Recupero il valore corrente object value = request.ActionParameters[currentParam.Key]; //Eseguo la serializzazione per testare se l'elemento da //errore o meno; se non lo da il contenuto è immutato, //altrimenti verrà rimpiazzato con il messaggio di errore JsonSerializer.Serialize(value); //Se la serializzazione non ha dato problemi, accetto il value cleanValue = value; } catch (Exception exc) { //Imposto il messaggio di errore in serializzazione cleanValue = $"[Serialization error: {exc.Message}]"; } //Accodo i valori nella lista "clean" cleanedParams.Add(cleanKey, cleanValue); } //Imposto i parametri "puliti" nella request request.ActionParameters = cleanedParams; //Eseguo la serializzazione della struttura dei parametri e dell'autenticazione string jsonParam = JsonSerializer.Serialize(request.ActionParameters, new JsonSerializerOptions { WriteIndented = true }); string authentication = StringifyAuthentication(request.Authentication); //Formatto i valori del verb, controller e azione return ($"(uid: {request.UniqueId}) {authentication} - [{request.HttpMethod}] {request.ControllerName}/{request.ActionName}({jsonParam})"); }
public void RequestTrace_OnAddTraceInformation_ThrowsInvalidOperationException() { // Arrange var model = new RequestTrace(); // Act // Assert Assert.Throws <InvalidOperationException>(() => model.AddTraceInformation()); }
protected override void OnModelCreating(ModelBuilder modelBuilder) { LogEntry.OnModelCreating(modelBuilder); RequestTrace.OnModelCreating(modelBuilder); AuditRecord.OnModelCreating(modelBuilder); DbUser.OnModelCreating(modelBuilder); DbLtcPharmacy.OnModelCreating(modelBuilder); }
/// <summary> /// Occurs before the action method is invoked. /// </summary> /// <param name="actionContext">The action context.</param> public override void OnActionExecuting(ActionExecutingContext actionContext) { //Validazione argomenti if (actionContext == null) { throw new ArgumentNullException(nameof(actionContext)); } //Esecuzione delle funzioni base base.OnActionExecuting(actionContext); //Nome del controller, action e http method (default) var controllerName = "<unknown>"; var actionName = "<unknown>"; var httpMethodName = "<unknown>"; //Cast della action al descrittore del controller ControllerActionDescriptor controllerDescriptor = actionContext.ActionDescriptor as ControllerActionDescriptor; //Se il cast va a buon fine if (controllerDescriptor != null) { //Imposto il nome del controller e la action controllerName = controllerDescriptor.ControllerName; actionName = controllerDescriptor.ActionName; //Se non ho constraints, esco if (controllerDescriptor.ActionConstraints != null) { //Tento il recupero del primo constraint su HTTP var single = controllerDescriptor.ActionConstraints .FirstOrDefault(c => c.GetType() == typeof(HttpMethodActionConstraint)); //Se ho trovato l'elemento if (single != null) { //Cast e recupero il valore var castedConstraint = (HttpMethodActionConstraint)single; httpMethodName = castedConstraint.HttpMethods.SingleOrDefault(); } } } //Eseguo la generazione della trace request _Request = TraceUtils.GenerateRequest(actionContext.HttpContext.User, httpMethodName, controllerDescriptor.ControllerName, controllerDescriptor.ActionName, actionContext.ActionArguments); //Traccio la request (se richiesto) if (EnableRequestTrace) { TraceRequest(_Request); } }
/// <summary> /// Action to display the detail trace records for a single request. /// </summary> /// <remarks> /// A NotFound response will be generated if there is no request /// in the current In-Memory buffer with that <paramref name="id"/>. /// </remarks> /// <param name="id">The unique identifier of the request. /// This is the <see cref="Guid"/> associated with the /// request as the traces were captured.</param> /// <returns>The <see cref="ActionResult"/>.</returns> public ActionResult TraceDetails(string id) { RequestTrace requestTrace = MemoryTraceStore.Instance.GetRequestTraces().FirstOrDefault(t => id == null || t.Id == id); if (requestTrace == null) { return(new HttpNotFoundResult()); } return(View("TraceDetails", requestTrace)); }
/// <summary> /// This method shows an example of request tracing using the 'using()' paradigm. /// </summary> public void TracedMethod_UsingParadigm() { using (RequestTrace request = new RequestTrace(requestEventSource)) { // TraceRequestStartEvent generated implicitly // we raise an example event through the default Application EventSource. // the TraceMessageEvent is also raised through the RequestEventSource. TraceMessageEvent.Raise("hello from using sample"); // TraceRequestEndEvent generated implicitly } }
public void RequestTrace_OnAddTraceInformation_AddsTraceInformation() { // Arrange var model = new RequestTrace(); // Act var activity = new Activity("TestOperation").Start(); model.AddTraceInformation(); // Assert Assert.NotNull(model.TraceId); Assert.NotNull(model.ParentId); }
private static RequestTrace CreateRequestTrace(TraceRecord traceRecord) { HttpRequestMessage request = traceRecord.Request; RequestTrace requestTrace = new RequestTrace { Id = traceRecord.RequestId.ToString(), Method = (request == null) ? String.Empty : request.Method.ToString(), Uri = (request == null || request.RequestUri == null) ? String.Empty : request.RequestUri.ToString(), Timestamp = traceRecord.Timestamp, Status = (int)traceRecord.Status, Reason = traceRecord.Status == 0 ? null : traceRecord.Status.ToString() }; return(requestTrace); }
public void nullo_does_not_record_steps_no_matter_what() { var trace = new RequestTrace(new IRequestTraceObserver[0], null, null); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Log("a"); trace.Current.AllSteps().Any().ShouldBeFalse(); }
public void WriteTrace( string service, RequestTraceDirection direction, DateTimeOffset dateBeginUtc, string url, string request, string response, Exception?exception = null ) { try { var trace = new RequestTrace( service, direction, dateBeginUtc, DateTimeOffset.UtcNow, url, request, response, exception ); using var connection = new SqlConnection(_settings.RequestTraceConnectionString); connection.Open(); var sqlStatement = $@" INSERT INTO {_settings.RequestTraceTableName} VALUES ( @Service, @Direction, @DateBeginUtc, @DateEndUtc, @Url, @Request, @Response, @Exception)"; connection.Execute(sqlStatement, trace); } catch (Exception exc) { _logger.Error("Could not create request trace", exc); } }
/// <summary> /// This method shows an example of request tracing using the try..finally paradigm. /// </summary> public void TraceMethod_TryFinallyParadigm() { RequestTrace request = new RequestTrace(requestEventSource); // TraceRequestStartEvent generated implicitly try { // we raise an example event through the default Application EventSource. // the TraceMessageEvent is also raised through the RequestEventSource. TraceMessageEvent.Raise("hello from try...finally sample"); } finally { request.Dispose(); // TraceRequestEndEvent generated implicitly } }
/// <summary> /// Add an <paramref name="item"/> to the collection. The item must /// have at least one string in the Id array. /// </summary> /// <param name="item">A RequestTrace object.</param> public void Add(RequestTrace item) { _dictionary.Add(item.Id.Peek(), item); }
/// <summary> /// Parse the message being logged by System.Net and store relevant event information. /// </summary> /// <param name="message">A message to write.</param> public override void WriteLine(string message) { var newRequestMatch = _newRequest.Match(message); if (newRequestMatch.Success) { var requestTrace = new RequestTrace(newRequestMatch.Groups[1].Value, new Uri(newRequestMatch.Groups[2].Value)); requestTrace.StartConnection(); _activeTraces.Add(requestTrace); return; } var associatedConnectionMatch = _associatedConnection.Match(message); if (associatedConnectionMatch.Success) { var requestTrace = _activeTraces[associatedConnectionMatch.Groups[2].Value]; _activeTraces.AddAliasKey(requestTrace, associatedConnectionMatch.Groups[1].Value); return; } var connectedMatch = _connected.Match(message); if (connectedMatch.Success) { var requestTrace = _activeTraces[connectedMatch.Groups[1].Value]; requestTrace.StopConnection(); requestTrace.StartWaiting(); return; } var responseStartedMatch = _responseStarted.Match(message); if (responseStartedMatch.Success) { var requestTrace = _activeTraces[responseStartedMatch.Groups[1].Value]; requestTrace.StopWaiting(); requestTrace.StartDownloadTime(); return; } var responseAssociatedMatch = _responseAssociated.Match(message); if (responseAssociatedMatch.Success) { var requestTrace = _activeTraces[responseAssociatedMatch.Groups[1].Value]; _activeTraces.AddAliasKey(requestTrace, responseAssociatedMatch.Groups[2].Value); return; } var responseCompleteMatch = _responseComplete.Match(message); if (responseCompleteMatch.Success) { var requestTrace = _activeTraces[responseCompleteMatch.Groups[1].Value]; requestTrace.StopDownloadTime(); _activeTraces.Remove(requestTrace); // TODO: At this point the request is done, use this time to store & forward this log entry Debug.WriteLine(requestTrace); return; } var faultedMatch = _requestException.Match(message); if (faultedMatch.Success) { var requestTrace = _activeTraces[responseCompleteMatch.Groups[1].Value]; requestTrace.Faulted(); _activeTraces.Remove(requestTrace); // TODO: At this point the request is done, use this time to store & forward this log entry Debug.WriteLine(requestTrace); } }
/// <summary> /// Trace request of action /// </summary> /// <param name="request">Request trace</param> protected override void TraceRequest(RequestTrace request) { //Non eseguo nessun tracciamento della request; eseguendo //l'override non viene tracciato nulla nemmeno nella classe base }
/// <summary> /// Given an <paramref name="item"/> in the collection, add another key /// that it can be looked up by. /// </summary> /// <param name="item">Item that exists in the collection</param> /// <param name="key">New key alias</param> public void AddAliasKey(RequestTrace item, string key) { item.Id.Push(key); _dictionary.Add(key, item); }