Is it possible to add a custom variable to the internalLogFile attribute in the nlog.config file, like ProjectName in internalLogFile="c:\logs\${gdc:ProjectName}\internal-nlog.txt"?
I tried this:
<nlog internalLogFile="c:\logs\${gdc:ProjectName}\internal-nlog.txt">
...
</nlog>
and
private static void ConfigureLogging(IServiceCollection services)
{
GlobalDiagnosticsContext.Set("ProjectName", "some-project-name");
LogManager.LoadConfiguration("nlog.config");
services.AddLogging(loggingBuilder =>
{
loggingBuilder.AddConfiguration(Config.GetSection("Logging"));
loggingBuilder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
loggingBuilder.AddNLog();
});
}
But LoadConfiguration throws an error (caught as first-chance exception in VS, so it's actually silently ignored):
System.IO.IOException: The directory name is invalid. : 'c:\logs\${gdc:ServiceRunnerFolder}'
I stepped through NLog code and it seems it only calls ExpandFilePathVariables to expand some known environment variables before setting the filename.
Is there a way to use a custom variable for this filename, without creating environment variables?
Never mind, I found the docs, it seems it's not possible as of NLog 5:
When you configure NLog using Configuration File, you can enable
internal logging by setting the following attribute on the
element:
internalLogFile="file.txt" - adding
internalLogFile cause NLog to write its internal debugging messages to
the specified file. This includes any exceptions that may be thrown
during logging.
Note: only a few layouts are supported, as the
internal log needs to be as stable as possible.
NLog 4.6+: Environment
Variables are also supported: e.g. %appdata% or %HOME%
NLog 4.6+:
Supports renderers (without options): ${currentdir}, ${basedir},
${tempdir}
NLog 4.7.1+: Supports renderer (without options):
${processdir}
NLog 5.0+: Supports renderers (without options):
${commonApplicationDataDir}, ${userApplicationDataDir},
${userLocalApplicationDataDir}
Instead of using ${gdc} and GlobalDiagnosticsContext.Set("ProjectName", "some-project-name"); then just update the InternalLogger directly:
var projectName = "some-project-name";
NLog.Common.InternalLogger.LogFile = $"c:\logs\{some-project-name}\internal-nlog.txt";
See also: https://github.com/NLog/NLog/wiki/Internal-Logging#example-with-internal-logging-from-code
Related
I am trying to provide an HttpClient from the outside to my ktor server so that I can mock external services and write tests, however I get this exception when I run my test:
Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `Compression`
io.ktor.server.application.DuplicatePluginException: Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `Compression`
at app//io.ktor.server.application.ApplicationPluginKt.install(ApplicationPlugin.kt:112)
at app//com.example.plugins.HTTPKt.configureHTTP(HTTP.kt:13)
at app//com.example.ApplicationKt.module(Application.kt:14)
at app//com.example.ApplicationTest$expected to work$1$1.invoke(ApplicationTest.kt:39)
at app//com.example.ApplicationTest$expected to work$1$1.invoke(ApplicationTest.kt:38)
and thats a bit unexpected to me because I am not applying the Compression plugin twice as far as I can tell. If I run the server normally and manually call my endpoint with curl then it works as expected. What am I doing wrong?
I added a runnable sample project here with a failing test.
sample project
official ktor-documentation-sample project.
The problem is that you have the application.conf file and by default, the testApplication function tries to load modules which are enumerated there. Since you also explicitly load them in the application {} block the DuplicatePluginException occurs. To solve your problem you can explicitly load an empty configuration instead of the default one:
// ...
application {
module(client)
}
environment {
config = MapApplicationConfig()
}
// ...
I xUnit test my ASP.NET Core web app, and my test class includes:
this.host = Program.CreateHostBuilder(Array.Empty<string>()).Build();
in order to access host.Services.
I discover that the host has Environment=Production. So the configuration seen in my startup file ignores appsettings.Development.json.
How do I inject or force host to have Environment=Development?
Preferably without any code in the web app itself.
(Context: I'm using JetBrains Rider. I find nothing in Rider setup or configuration that lets me choose an Environment for a UnitTest session. But if there is a solution on that line the question still stands)
I had assumed—wrongly—that I might fix it with this:
this.host = Program.CreateHostBuilder(
"ASPNETCORE_ENVIRONMENT=Development"
).Build();
because the docs say
The default configuration loads environment variables and command line arguments prefixed with DOTNET_ and ASPNETCORE_
but what fixed it was:
this.host = Program.CreateHostBuilder(
"ENVIRONMENT=Development"
).Build();
With this, the Configuration element then picked up the appsettings.Development.json file instead of ignoring it.
( So now I wonder whether part of the env variable processing is done by the dotnet executable before reaching Program.Main() )
Using the Microsoft.Extensions.Configuration package, I have the following line in my Program.cs file:
config.AddUserSecrets<Startup>(optional: false);
With a populated secrets.json file present, this line works as presumed. Alternatively, I would assume that a missing secrets.json file should trigger an exception of some sort, since I marked it as required; however, no exception is thrown.
Is this to be expected? My ultimate goal is to give developers an obvious indicator if they pull a project out of source control and attempt to run it without also having created a correlated secrets file.
I'm trying to get double underscore for configurations to work in ASP.Net core 3.1 as described here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration&view=aspnetcore-3.1#environment-variables
I've written some code for configurations that does this manually
check Env Var
check AppSettings...json files
but I saw that in .net 3.1 this is supposed to be supported by default with one caveat around hierarchal settings on unix platforms. In this case you can't use this syntax
Configuration["SomeSection:SomeConfig"]
to resolve this environment variable
## Environment Var
SomeConfig:SomeConfig
Because linux doesn't support colons in Env Var names. This would however work if code was deployed to a windows machine. So instead .net seems to indicate you can use this syntax
Configuration["SomeSection__SomeConfig"]
which will resolve any of the following configurations
// AppSettings...json
{
"SomeSection" {
"SomeConfig": "some value"
}
}
or
# Environment Var on linux
SomeConfig__SomeConfig
or
// Environment Var on windows
SomeConfig:SomeConfig
Does anyone know what I'm doing wrong?
Edit:
Note that I know the answer to this questions and will happily answer it if it's is reopened.
I had misunderstood the documentation. The way it works is that if you use this code in your Startup.cs
Configuration["SomeSection:SomeConfig"]
it will correctly resolve
// AppSettings...json
{
"SomeSection" {
"SomeConfig": "some value"
}
}
from your various appsettings*.json files.
However, if you define an environment variable with the name SomeSection:SomeConfig that will be used instead of the appsettings.json value which is a great feature. This is often desirable when running the app in a docker container.
However, if are on a Linux operation system it's not possible to create an environment variable with the name SomeSection:SomeConfig. So if you are on Linux machine or in a Linux container, instead if you name your environment variable SomeSection__SomeConfig with a __ (double underscore) instead of a : then you could access like below:
Configuration["SomeSection:SomeConfig"]
Before v2:
RouteTable.Routes.MapHubs();
In v2, MapHubs does not exist anymore. The wiki says to add a Startup class and a Configuration method and a call to app.MapHubs().
namespace MyAssembly
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//Before v2
//RouteTable.Routes.MapHubs();
app.MapHubs();
}
}
}
But the method is never called, no error occurs, and ... no hub are setup.
I suppose there is some code to add to global.asax.cs
What is the secret ?
Try defining [assembly : OwinStartup(typeof(MyAssembly.Startup))] to see if your Startup class is being picked up.
EDIT: removed lines not relevant.
Solution !
<appSettings>
<add key="owin:AppStartup" value="MyNameSpace.Startup, MyNameSpace" />
</appSettings>
plus update both MVC4 (not to prerelease, but to latest stable version) and SignalR/owin nugets.
plus fix bugs in js client :
if disconnectTimeout=999000 then it is disabled. Must be set server-side with: GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(999);
note: server side can not set a value < 6 (signalr throws an exception if DisconnectTimeout < 6). So use this magic number.
webSockets: set connection.socket = null in sockettransport, otherwise the call to start fails after a (manual) call to stop
serverSentEvents: prevent error caused by a reconnection attempt when the window is unloading
chrome fails with exception if signalr hub url not available (temporarily) : Instead of giving up try the next available protocol / try to reconnect.
I was able to get the 2.0 beta working by
Removing all references to the older version of SignalR, ie nuget uninstall of the library and double checking /bin
Installed SignalR 2.0.0-beta2 via Package Manager Console Install-Package Microsoft.AspNet.SignalR -Pre
Following the steps in the 1.x to 2.0 migration outlined here
And most importantly changing the project config to use Local IIS Web server instead of Visual Studio Developer Server (Cassini).
More info in the question/answer I posted here
In web.config there must be a fully qualified name of the class, e.g.
<appSettings>
<add key="owin:AppStartup" value="**My.Name.Space.Startup**, **AssemblyName**" />
</appSettings>
I had a problem when I put namespace instead of assembly name, but with the fully qualified name it works without any other changes to web.config!
UPDATE: I also followed the steps from the link: http://www.asp.net/vnext/overview/latest/release-notes#TOC13, i.e. removed a NuGet package "Microsoft.AspNet.SignalR.Owin"