Web Api: Disable tracing while the server is running - asp.net-web-api

I can enable tracing by replacing the default No Op trace writer.
GlobalConfiguration.Configuration.Services.Replace(typeof(ITraceWriter), new SimpleTracer());
But how can I disable (and enable it again) while the server is running?
The Enum "TraceLevel" has the option TraceLevel.Off.
Is there a way to set the tracing-framwork form web api to TraceLevel.Off?

Take a look at this article here.
WebApi does not provide any way to configure trace writers regarding their current category or level.
And
Determining which categories and levels are currently enabled is the
responsibility of the ITraceWriter implementation. The Web API
framework has no concept of trace configuration or determining which
categories and levels are enabled.
The intent of this approach is to rely on the ITraceWriter
implementation’s own mechanisms to configure what gets traced and
where.
For example, if you use an NLog-specific ITraceWriter, you should
configure tracing through NLog configuration mechanisms.
In short if you want to enable and disable your tracing or chose not to log a trace for a particular level it is up to you to implement inside your SimpleTracer.
You could create your own threadsafe singleton TraceConfiguration (akin to GlobalConfiguration) implementation to control the trace configuration to allow toggling on or off within the code.
public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action<TraceRecord> traceAction)
{
if(TraceConfiguration.Configuration.IsEnabled)
{
//trace
}
}
Or you could set and access properties on the request object to determine whether to enable tracing or not. This could be set by ActionFilters on actions and controllers or even set within the controller.
public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action<TraceRecord> traceAction)
{
if(request.Properties["SupressTracing"] as string != "true")
{
//trace
}
}
Or as the article suggests if you are using NLog or Log4Net etc it is up to you set the levels enabled via config etc.

Related

How to set FiddlerCore up to monitor all system traffic?

We are evaluating FiddlerCore for a use-case. Basically, for now we just want to catch all of the endpoints/urls being requested on a system. This works fine in Fiddler, no issues. But we only want to catch them while a certain vendor software is open. So we want to write a plugin to that software that will run when it launches, and then exit when it exits. Hence, using FiddlerCore (hopefully).
As proof-of-concept, I just made a simple app, one form with a textbox, that it should just append each url into the textbox. Simple as simple can be. However, it's not doing anything. I run the app, then refresh a page in my browser, and ... nothing.
Here is the entire (non-generated) code of my program...
using Fiddler;
using System;
using System.Windows.Forms;
namespace ScratchCSharp {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
FiddlerApplication.Startup(8888, FiddlerCoreStartupFlags.Default);
}
private void FiddlerApplication_AfterSessionComplete(Session s) {
textBox1.Invoke((Action)delegate () {
AddText(s.fullUrl);
});
}
public void AddText(string text) {
textBox1.Text += $"{text}\n";
}
}
}
After a little more poking around, I see that FiddlerApplication.IsSystemProxy is returning false. Seems to have to do with that the Startup flag to set as system proxy is no longer honored, and it tells you now to use the Telerik.NetworkConnections.NetworkConnectionManager to set it as the system proxy. But I can't find anywhere that actually says how to do that. The closest thing I could find is this thread which seems to be their official answer to this question. However, it only goes into a lot of talk about WHY they deprecated the flag, and what their thinking was in how they designed its replacement, but not actually into HOW TO USE the replacement. The Demo app also does NOT use these libraries (probably why it doesn't catch anything either).
The biggest problem though, is that the NetworkConnectionsManager class has no public constructor, so you can't create an instance. It is not inheritable, so you can't make a subclass instance. All of the methods on it are instance methods, not static/shared. And there seems to be no method in the libraries which will create an instance of NetworkConnectitonsManager for you.
So while the class is clearly designed to be used as an instance (hence the methods not being static/shared, there doesn't actually seem to be any way to create an instance.
Any help on how to set this thing up to catch all the outgoing URLs on the system?
You can use the following code for starting Fiddler Core and registering it as a system proxy:
FiddlerCoreStartupSettings startupSettings =
new FiddlerCoreStartupSettingsBuilder()
.ListenOnPort(fiddlerCoreListenPort)
.RegisterAsSystemProxy()
.ChainToUpstreamGateway()
.DecryptSSL()
.OptimizeThreadPool()
.Build();
FiddlerApplication.Startup(startupSettings);
Some of the methods are obsolete for now, but I would recommend to stick with them until the NetworkConnectionManager API is improved and finalized.
Also, there is a sample application (that FiddlerCore installer installs on the Desktop), which is useful for a starting point with the development.

How to access session from a view in ASP .NET Core MVC 1.0

I am trying to access session data from inside a view.
Use Case: I'm storing status messages in the session that will be displayed at the top of the page. Currently I implemented this by using a DisplayMessages() function that sets some ViewData[....] properties and calling it at the beginning of every controller action.
Goal: I want to only set the status message once without needing additional code in the controller to display the messages on the next page load.
So I'm trying to access the messages that are stored in the session directly from the view.
So far I have tried the following:
Dependency Injection of an IHttpContextAccessor (doesn't seem to work anymore with ASP .NET Core MVC 1.0.0
Creating a static class to access the session, including the change from next() to next.invoke() suggested in the comment
This didn't work. I could access the HttpContext and Session.IsAvailable was true, but there was no data in the session.
The following should work in the view: Context.Session.TryGetValue
If you are using the SessionExtensions then Context.Session.GetString will work.
Injecting IHttpContextAccessor does work, but starting with ASP.NET Core 1.0.0 RC2, the IHttpContextAcessor is not registered by default, because it has significant performance overhead per request. See this GitHub announcement for more information.
Tratcher posted:
IHttpContextAccessor can be used to access the HttpContext for the current thread. However, maintaining this state has non-trivial performance costs so it has been removed from the default set of services.
Developers that depend on it can add it back as needed:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
But in your use case, I would suggest using a ViewComponent, which is a reusable piece of View with logic, that do not depend on a controller.
The documentation can be found here.
In your Views you would simply embed it with
#await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
or
#Component.Invoke("PriorityList", new { maxPriority = 2, isDone = false })
for synchronous calls.

Anyone using Serilog.Extras.MSOwin

I was wondering if anyone has seen a demo/example of using the Serilog.Extras.MSOwin package with a web api project or a example/tutorial of using Serilog with a web api project.
Any help greatly appreciated,
Jim
I will take this as question as "How do I used Serilog.Extras.MSOwin?" and given it is currently a rather small library answer here.
This reflects the current library (1.4.102) and is subject to change in the future.
Serilog.Extras.MSOwin provides two things: a Microsoft.Owin.Logging.ILoggerFactory implementation to have OWIN's logging infrastructure write to Serilog (more details about logging in OWIN in this blog post) and Guid identifier (RequestId) for each web request to aid in associating logged events.
The Logging integration is done with the following:
IAppBuilder app = ...;
Serilog.ILogger logger = ...'
app.SetLoggerFactory( new Serilog.Extras.MSOwin.LoggerFactory( logger ) );
The request id functionality needs to be registered in the OWIN pipeline:
IAppBuilder app = ...;
app.UseSerilogRequestContext("RequestId");
You will want to register that very early in the pipeline because any logging occurring before that pipeline step will not have the request id available.
You also need will need to retrieve it from the LogContext using Enrich.FromLogContext() and add that property to what you write to your sinks. For example,
const string DefaultOutputTemplate =
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} ({RequestId}) {Message}{NewLine}{Exception}";
ILogger logger =
new LoggerConfiguration().Enrich.FromLogContext()
.WriteTo
.RollingFile(
"log.txt",
outputTemplate: DefaultOutputTemplate)
.CreateLogger();
Serilog.Extras.MSOwin was superseded by SerilogWeb.Owin (which has since also been discontinued.)

What's the best way to detect the start of a session (similar to Global.ashx's Session_Start) when using ServiceStack SessionFeature?

I've enabled Sessions support in service stack like:
container.Register<IRedisClientsManager>(c => container.Resolve<PooledRedisClientManager>());
container.Register<ICacheClient>(c => c.Resolve<IRedisClientsManager>().GetCacheClient());
container.Register<ISessionFactory>(c => new SessionFactory(c.Resolve<ICacheClient>()));
//RE: https://github.com/ServiceStack/ServiceStack/wiki/Sessions
Plugins.Add(new SessionFeature());
I see that ss-id and ss-pidd cookies are set upon visiting the site, however I would like to know when a session is started (i.e., first request from that user) so i can capture the incoming referrer url.
Using traditional asp.net sessions, i'd use Session_Start in Global, however this doesn't fire for me while using SS sessions.
Is there a good way to detect this session start event when using ServiceStack? I didn't find any reference in my queries online, or on the ServiceStack Sessions wiki.
There is currently no "Session Started" event in ServiceStack's Sessions feature, but there are some events on IAuthSession that might be useful to use instead, e.g:
public interface IAuthSession
{
...
void OnRegistered(IServiceBase registrationService);
void OnLogout(IServiceBase authService);
void OnAuthenticated(IServiceBase authService, IAuthSession session,
IOAuthTokens tokens, Dictionary<string, string> authInfo);
}
If you still would like to see an OnSessionStarted event request it as a feature in ServiceStack's GitHub issues (and include your use-case), so we can keep track of it.

Determine if Glimpse is running during Application_BeginRequest()

I have installed Glimpse (Glimpse MVC4) and MiniProfiler (with EF support).
I also installed the MiniProfiler plugin for Glimpse.
I have that all wired up and working. I want to allow the configuration of Glimpse to determine if MiniProfiler should start profiling. That is, if Glimpse is enabled (through Glimpse.axd not via a config setting) I want to call MiniProfiler.Start() in the Application_BeginRequest() method. So, something like this:
protected void Application_BeginRequest()
{
if (Glimpse.IsRunning)
{
MiniProfiler.Start();
}
}
Is there a way to determine if Glimpse is enabled?
Technically there is a way, but I'd call it hacky at best. I'll let you decide if it is a good fit for your purposes.
var policyString = HttpContext.Current.Items["__GlimpseRequestRuntimePermissions"].ToString();
RuntimePolicy glimpsePolicy;
RuntimePolicy.TryParse(policyString, out glimpsePolicy);
if (!glimpsePolicy.HasFlag(RuntimePolicy.Off))
{
MiniProfiler.Start();
}
The reason I call it a hack is because while Glimpse may be On at the beginning of request, it may be later turned Off.
An example of this behavior is when Glimpse automatically shuts off once ASP.NET begins to report an unsupported media type, like an image. ASP.NET does not have the ability to know the media type until after the HTTP Handler has run. In this case, Glimpse will say that it is on at the beginning of the request, but then will be off at the end of it.

Resources