Hooking into SignalR event in Blazor ServerSide - blazor-server-side

I have found this piece of code for the default logging mechanism provided by Microsoft:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.AddFilter(
"Microsoft.AspNetCore.SignalR", LogLevel.Trace);
logging.AddFilter(
"Microsoft.AspNetCore.Http.Connections",
LogLevel.Trace);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
My set for Serilog is as follows:
public class Program
{
public static void Main(string[] args)
{
try
{
using IHost host = CreateHostBuilder(args).Build();
host.Run();
}
catch (Exception ex)
{
if (Log.Logger == null || Log.Logger.GetType().Name == "SilentLogger")
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
}
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
private static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory(Register))
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.CaptureStartupErrors(true)
.ConfigureAppConfiguration(config => { config.AddJsonFile("appsettings.Local.json", optional: true); })
.UseSerilog((hostingContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.Enrich.WithProperty("ApplicationName", typeof(Program).Assembly.GetName().Name)
.Enrich.WithProperty("Environment", hostingContext.HostingEnvironment);
#if DEBUG
loggerConfiguration.Enrich.WithProperty("DebuggerAttached", Debugger.IsAttached);
#endif
});
});
private static void Register(ContainerBuilder builder) => builder.RegisterLogger(autowireProperties: true);
}
How do I add SignalR filters to my setup?

In Serilog terminology you need to override the minimum level for the Microsoft SignalR namespaces.
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args)
.UseSerilog((context, config) =>
{
/*
* the rest of the Serilog configuration here
*/
config.MinimumLevel.Override("Microsoft.AspNetCore.SignalR", LogEventLevel.Debug);
config.MinimumLevel.Override("Microsoft.AspNetCore.Http.Connections", LogEventLevel.Debug);
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

Related

ASP.NET CORE Web API Serilog and ElasticSearch logging not working on IIS but works locally

I configured .NET 5 Web API Serilog and Elasticsearch, it works normally on local when run application and send request from REST client. But when i publish it on IIS and made same request to same endpoints it is not working entirely. No any logs from app published on IIS.
public class Program
{
public static void Main(string[] args)
{
ConfigureLogging();
CreateHost(args);
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseWebRoot("client-app");
})
.ConfigureAppConfiguration(configuration =>
{
configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
configuration.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true);
})
.UseSerilog();
private static void ConfigureLogging()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true)
.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.WriteTo.Debug()
.WriteTo.Console()
.WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment))
.Enrich.WithProperty("Environment", environment)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
private static ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment)
{
return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"]))
{
AutoRegisterTemplate = true,
IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name?.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}-{DateTime.UtcNow:yyyy-MM}"
};
}
private static void CreateHost(string[] args)
{
try
{
CreateHostBuilder(args).Build().Run();
}
catch (System.Exception ex)
{
Log.Fatal($"Failed to start {Assembly.GetExecutingAssembly().GetName().Name}", ex);
throw;
}
}
}
Elastic uri has not restriction on IIS

ASP.NET core how could i get my websites url/hostname when the program starts up

I need to get my site's host name so I can change the directory of the JSON file that I am adding to my project. I just have no clue how I can collect the URL.
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) => {
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
config.SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("wwwroot/sites/"environment"/"environment".json", optional: false, reloadOnChange: true);
})
.UseStartup<Startup>()
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddLog4Net();
logging.SetMinimumLevel(LogLevel.Information);
});
You can get the url in the following ways.
public static void Main()
{
var host = BuildWebHost(null);
host.Start();
var serverAddress = host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
foreach (var address in serverAddress)
{
var uri = new Uri(address);
var port = uri.Port;
Console.WriteLine($"Bound to port: {port}");
}
host.WaitForShutdown();
}
private static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

Configure NServicebus in Asp.net Core 5

I am using the NServiceBus.Extensions.Hosting extension to configure NServicebus
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseNServiceBus(c =>
{
var endpointConfiguration = new EndpointConfiguration("nsb.medusa");
endpointConfiguration.UseTransport<RabbitMQTransport>().ConnectionString("How do I access app settings?");
endpointConfiguration.SendOnly();
return endpointConfiguration;
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
The problem I am having is that I don't know how to get an instance of IConfiguration from a IHostBuilder. I need IConfiguration so I can get the connection string to RabbitMQ.
Also can this be moved to the startup class?
Microsoft has some excellent documentation. After reading it I just added two lines of code and I can now access the configuration.
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseNServiceBus(c =>
{
var configuration = c.Configuration; /* New */
var cnnStr = configuration.GetSection("mq:connection").Value; /* New */
var endpointConfiguration = new EndpointConfiguration("nsb.medusa");
endpointConfiguration.UseTransport<RabbitMQTransport>().ConnectionString(cnnStr);
endpointConfiguration.SendOnly();
return endpointConfiguration;
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

Implementing Autofac in .NET Core 3 Console Application, injecting IServiceProvider into Config class (not working?)

This might be a "stupid" question but I'm kind of lost, I'm trying to implement Autofac into a working .NET Core 3.1 Console Application but can't seem to get some things to work.
I have a class named Config.cs that are used at multiple places the console application so I'd like to keep that file so as to not rewrite this implementation.
Here is that file
public class Config : IConfig
{
readonly IConfiguration _config;
public Config(IServiceProvider services)
{
_config = (IConfiguration)services.GetService(typeof(IConfiguration));
}
public string StorageConnectionString => _config["ConnectionStrings:StorageConnectionString"];
public string SqlConnectionString => _config["ConnectionStrings:SqlConnectionString"];
public string MongoConnectionString => _config["ConnectionStrings:MongoConnectionString"];
public string RayGunApiKey => _config["RayGunApiKey"];
public string ElasticsearchUri => _config["Uris:ElasticsearchUri"];
public string StatsDUri => _config["Uris:StatsDUri"];
public string Get(string key) => _config[key];
}
This is first used in Functions.cs in a TimeTrigger:
public class Functions
{
readonly IConfig _config;
public Functions(ILogger<Functions> logger, IConfig config)
{
_logger = logger;
_config = config;
}
public void Run([TimerTrigger("00:00:01", RunOnStartup = true, UseMonitor = true)]TimerInfo myTimer)
{
...
}
}
But when I start the console application an error is thrown
System.InvalidOperationException: Unable to resolve service for type 'DataPurger.IConfig' while attempting to activate 'DataPurger.Functions'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IServiceProvider serviceProvider) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs:line 37
at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IFunctionInstanceEx functionInstance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs:line 32
at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.<>c__DisplayClass1_1.<.ctor>b__0(IFunctionInstanceEx i) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs:line 20
at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.Create(IFunctionInstanceEx functionInstance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs:line 26
at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.CreateInstance(IFunctionInstanceEx functionInstance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 44
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.Initialize() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 846
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 117
This injection works without Autofac, but I'm "forced" to implement it since Autofac is used in every other project where I'm working.
Here is the Program.cs
static void Main(string[] args)
{
RegisterServices();
CreateHostBuilder(args).Build().RunAsync().Wait();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
config.AddEnvironmentVariables();
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
config.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true,
reloadOnChange: true);
})
.ConfigureLogging((context, b) =>
{
b.AddConsole();
})
.ConfigureServices(s =>
{
s.AddLogging();
s.AddOptions();
})
.ConfigureWebJobs(builder =>
{
builder.AddAzureStorageCoreServices();
builder.AddExecutionContextBinding();
builder.AddTimers();
})
.UseConsoleLifetime()
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
static void RegisterServices()
{
var collection = new ServiceCollection();
var builder = new ContainerBuilder();
builder.RegisterModule<BaseModule>();
builder.Populate(collection);
var container = builder.Build();
_serviceProvider = new AutofacServiceProvider(container);
}
public class BaseModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Config>().As<IConfig>().SingleInstance();
}
}
What am I doing wrong, I'm sure there is something missing or that I did not understand correctly?
It is my sample for ASP .Net core 3.1
in Program.cs I changed
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<-like yours
.UseSerilog()
.ConfigureLogging((context, builder) => builder.AddSerilog())
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
and I added to Startup.cs
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<QuartzWrapper>().As<IQuartzWrapper>().SingleInstance();
builder.Register(provider => new JobFactory(provider)).As<IJobFactory>().InstancePerDependency();
builder.RegisterType<JobClass>().As<IJob>().InstancePerDependency();
}
and I used the next packages:
Autofac - Version="5.1.2"
Autofac.Extensions.DependencyInjection - Version="6.0.0"
You need to try and check how it works without the module, change
builder.RegisterModule<BaseModule>();
to
builder.RegisterType<Config>().As<IConfig>().SingleInstance();

Asp.net core get logger in ConfigureAppConfiguration

I would like to use logger in "TODO" line, because I need to log when I add a "AddJsonConfigurationSourceDecryption" method, Is there any way to get a logger?
Logging in ASP.NET Core
public class Program
{
public static void Main(string[] args)
{
ILogger<Program> logger = null;
try
{
var host = CreateWebHostBuilder(args).Build();
ApplicationLogging.LoggerFactory = host.Services.GetRequiredService<ILoggerFactory>();
logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("start thin API service...");
host.Run();
}
catch (Exception ex)
{
logger?.LogError(ex, "Stopped program because of exception");
throw;
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseKestrel(option => option.AddServerHeader = false)
.ConfigureLogging((host, builder) => { builder.SetMinimumLevel(LogLevel.Trace); })
.UseNLog()
.ConfigureServices(services => services.AddAutofac())
.ConfigureAppConfiguration((context, builder) =>
{
//TODO: Logger.............
builder.SetBasePath(Directory.GetCurrentDirectory());
builder.AddJsonConfigurationSourceDecryption();
})
.UseStartup<Startup>();
}
}
#0xced answered this question here
How to create a LoggerFactory with a ConsoleLoggerProvider?
as of dotnetcore3.1 the code could be written this way
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args).ConfigureAppConfiguration(
(hostContext, config) =>
{
var loggerFactory = LoggerFactory.Create(
builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
.AddFilter("YourProgramNamespsace.Program", LogLevel.Debug)
.AddConsole();
});
var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Hello from ConfigureAppConfiguration");
...
})