For example, I have config in package.json
"build": {
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64",
"ia32"
]
}
]
}
}
And I want validate this before start build process or CI/CD pipeline.
Example of how electron-builder check config.
Then we can try to use the same method and tools - #develar/schema-utils and scheme which uses electron-builder for validation
// validate.js
const validate = require('#develar/schema-utils');
const schema = require('./schemas/schema.json');
const options = {
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64",
"ia32"
]
}
]
}
};
const configuration = {
name: 'electron-builder'
};
try {
validate(schema, options, configuration);
} catch(e) {
console.log(e.message)
}
If we execute command:
node validate.js
We have not something input.
But if we use wrong config. For example,
const options = {
"win": {
"target": [
{
"target": ["nsis"],
"arch": [
"x64",
"ia32"
]
}
]
}
};
The output of the command will be:
Invalid configuration object. electron-builder has been initialized using a configuration object that does not match the API schema.
- configuration.win.target[0].target should be a string.
-> The target name. e.g. `snap`.
Related
I'm using Krakend as API-Gateway, and my configuration looks like this :
{
"plugin": {
"folder": "/etc/krakend/plugins/authenticator/",
"pattern":".so"
},
"port": 8080,
"extra_config": {
"github_com/devopsfaith/krakend/transport/http/server/handler": {
"name": "authenticator"
}
},
"endpoints": [
{
"output_encoding": "no-op",
"backend": [
{
"encoding": "no-op",
"host": [
"127.0.0.1:8080"
],
"url_pattern": "/api/v1/address/{id}",
"method": "GET"
}
],
"endpoint": "/api/v1/addresses/{id}",
"method": "GET"
}
],
"name": "gateway",
"timeout": "30s",
"version": 2
}
I want to pass some metadata per end point and access it in my predefined plugin .
In this case authenticator plugin.
What you are trying to achieve is perfectly possible, and is the way all components work in KrakenD. Your plugin can access the KrakenD configuration using the namespace you define. For instance, you could set your metadata like this (I am assuming you have in your Go code a pluginName = "slifer2015-authenticator" ):
{
"endpoints": [
{
"output_encoding": "no-op",
"backend": [
{
"encoding": "no-op",
"host": [
"127.0.0.1:8080"
],
"url_pattern": "/api/v1/address/{id}"
}
],
"endpoint": "/api/v1/addresses/{id}",
"extra_config": {
"github_com/devopsfaith/krakend/transport/http/server/handler": {
"name": [
"slifer2015-authenticator",
"some-other-plugin-here"
],
"slifer2015-authenticator": {
"Metadata1": "value1",
"Metadata2": {
"Some": 10,
"Thing": 100,
"Here": "60s"
}
}
}
}
}
]
}
Then your metada is available in the extra parameter when the registerer kicks in, inside the key you have chosen.
func (r registerer) registerHandlers(ctx context.Context, extra map[string]interface{}, h http.Handler) (http.Handler, error) {
``
I have developed a net core 3.1 service for windows, the service works fine, but fails to write the log file.
during debugging Serilog writes the file correctly, but once installed with sc it writes nothing.
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.UseSerilog((hostingContext, loggerConfig) =>
loggerConfig.ReadFrom.Configuration(hostingContext.Configuration)) // custom log event
.ConfigureServices((hostContext, services) =>
{
IConfiguration configuration = hostContext.Configuration; //prendi la configurazione
ServiceInfo siOption = configuration.GetSection("ServiceInfo").Get<ServiceInfo>();
services.AddSingleton(siOption);
services.AddHostedService<Worker>();
});
}
appsettngs.json
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.RollingFile" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"WriteTo": [
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "(#Level = 'Error' or #Level = 'Fatal' or #Level = 'Warning')"
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/ex_.log",
"outputTemplate": "{Timestamp} [{Level:u3}] {Message}{NewLine}{Exception}",
//"outputTemplate": "{Timestamp:o} [{Level:u3}] ({SourceContext}) {Message}{NewLine}{Exception}",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
}
]
}
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName"
],
"Properties": {
"Application": "ORAMS-II Service Status Telegram"
}
}
}
I don't know what the problem could be, installed on a linux machine writes the file correctly
I used to ship my data to Elasticsearch by FileBeat-LogStash pipeline. Processed my logs which was created via log4net, mutated them, and sent required fields towards elastic.
Now I would like to replace my logic by removing the FileBeat and Logstash and make use of Serilog and it's elasticsearch sink.
To broader the picture I have an API endpoint which receives requests which I need to log to a textual file as they are so I need a File sink. Further down the code, my business logic will make use of data received and among else create an object which I then need to ingest to an index at elastic.
What's the best approach for this, have one Serilog instance and use some kind of filtering or have two Serilog instances? I'm closer to decorating (enrich) my cases and then using sinks by filtering (one Serilog instance) but because I'm a novice with Serilog I don't know how to set up the whole thing.
The abbreviated code would be something like this,
My controller class:
public class RequestController : ControllerBase
{
private readonly BLService _service = new BLService(Log.Logger);
[Route("Test")]
[HttpPost]
public IActionResult Test([FromBody]SampleRequest request)
{
var logId = Guid.NewGuid().ToString();
using (LogContext.PushProperty("LogId", logId))
Log.Information("{#request}", request);
var tran = new SampleTran
{
SampleTranType = "Test",
SampleTranId = request.Id,
EventTime = DateTime.Now
};
_service.ProcessTransaction(tran);
return new OkResult();
}
}
And my service where I'm adding property "Type" with constant value "ElkData" which I could then filter on:
public class BLService
{
private readonly ILogger _log;
public BLService(ILogger logger)
{
_log = logger.ForContext("Type", "ElkData");
}
public void ProcessTransaction(SampleTran transaction)
{
var elkData = DoSomeStuffAndReturnElkTransactionToStore(transaction);
_log.Information("{#ElkData}", elkData );
}
}
One note, my text file should only contain raw requests (without elasticsearch data). So far I'm writing all to file, and my appsettings.json looks like this:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "C:\\DEV\\Logs\\mylog-.txt",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-ddTHH:mm:ss.fff zzz} [{Level:u3}] {Message:j}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext" ]
},
"AllowedHosts": "*"
}
I need to add the elastic part using filtering, am I right? Any help would be appreciated.
Here's how I managed to do what I need:
I've used ForContext to enrich my log items. So in the controller, I used:
var requestLog = Log.ForContext("Type", "Request");
requestLog.Information("Request: {#request}", request);//this needs to go to the log file
the code in BLservice stays the same and the filtering is described in the appsettings.json as:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "Type = 'ElkData'"
}
}
],
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "C:\\DEV\\Logs\\mylog-.txt",
"rollingInterval": "Day",
"outputTemplate": "{Timestamp:yyyy-MM-ddTHH:mm:ss.fff zzz} [{Level:u3}] {Message:j}{NewLine}{Exception}",
"shared": true
}
}
]
}
}
},
{
"Name": "Logger",
"Args": {
"configureLogger": {
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "Type = 'ElkData'"
}
}
],
"WriteTo": [
{
"Name": "Elasticsearch",
"Args": {
"nodeUris": "<your elastic url>",
"TypeName": "_doc",
"IndexFormat": "serilog_data",
"InlineFields": true,
"BufferBaseFilename": "C:\\DEV\\Logs\\elk_buffer"
}
}
]
}
}
}
]
}
}
So the file will contain everything that is logged out except logs that carry "Type = 'ElkData'" enrichment, those will end up in elasticsearch index.
Hope this simple approach will help some serilog novice out there someday
i need to configure appsettings to use serilog log and to separate same classes (identityserver4, query sql, application ) and redirect the output in dfferent file to analyze tha program flow.
I've installed serilog, serilog.settings.configuration, serilog.sinks.rollingfile, serilog.filters.extensions and serilog.sinks.console but i've not found some documentation to do that.
This is my Serilog section in appsetting:
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{ "Name": "LiterateConsole" },
{
"Name": "RollingFile",
"Args": { "pathFormat": "Logs/log-{Date}.txt" }
},
{
"Name": "RollingFile",
"pathFormat": "Logs/DBCommands-{Date}.log",
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "SourceContext = 'IdentityServer4'"
}
}
]
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Properties": {
"Application": "dsm.security"
}
}
Where i'm wrong ?
UPDATE
I would like to have the same result that i can obtain with the following code
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.ReadFrom.Configuration(Configuration)
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Default", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console(theme: AnsiConsoleTheme.Code)
.WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Error).WriteTo.RollingFile(#"Logs/Error-{Date}.log"))
.WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Fatal).WriteTo.RollingFile(#"Logs/Fatal-{Date}.log"))
.WriteTo.Logger(l => l.Filter.ByIncludingOnly(Matching.FromSource("dsm.security")).WriteTo.RollingFile(#"Logs/dsm.security-{Date}.log"))
.WriteTo.Logger(l => l.Filter.ByIncludingOnly(Matching.FromSource("IdentityServer4")).WriteTo.RollingFile(#"Logs/IdentityServer-{Date}.log"))
.WriteTo.Logger(l => l.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.EntityFrameworkCore")).WriteTo.RollingFile(#"Logs/EF-{Date}.log"))
// .WriteTo.RollingFile(#"Logs/Verbose-{Date}.log")
.CreateLogger();
I am unable to connect using artillery.io with setting engine = socketio, please find my configuration json below
socket error {"type":"Transport error", "description":400}
"scenarios": [
{
"name": "my test",
"engine": "socketio",
"flow": [
{
"emit": {
"channel": "command",
"namespace": "command"
}
},
{
"think": 1
}
]
}
]
"scenarios": [
{
"name": "my test",
"engine": "socketio",
"flow": [
{
"emit": {
"channel": "command"
"data": "hello"
"namespace": "/command"
}
},
{
"think": 1
}
]
}
]
Please try using above command