Why is Serilog LoggerEnrichmentConfiguration action not implemented - configuration

I am getting:
ArgumentException: Configuration for Action<Serilog.Configuration.LoggerEnrichmentConfiguration> is not implemented.
I've got a configuration something like this, loosely based on the sample:
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"LevelSwitches": { "$controlSwitch": "Verbose" },
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"MyApp.Something.Tricky": "Verbose"
}
},
"WriteTo:Async": {
"Name": "Async",
"Args": {
"configure": [
{
"Name": "File",
"Args": {
"outputTemplate": "{Timestamp:o} [{Level:u3}] ({Application}/{MachineName}/{ThreadId}/{ThreadName}) {Message}{NewLine}{Exception}"
}
}
]
}
},
"Enrich": [
"FromLogContext",
"WithThreadId",
{
"Name": "AtLevel",
"Args": {
"enrichFromLevel": "Error",
"configureEnricher": [ "WithThreadName" ]
}
},
{
"Name": "When",
"Args": {
"expression": "Application = 'MySample.Service'",
"configureEnricher": [ "WithMachineName" ]
}
}
],
"Properties": {
"Application": "MySample.Service"
},
"Destructure": [
{
"Name": "With",
"Args": { "policy": "MySample.Logging.CustomPolicy, MySample.Service" }
},
{
"Name": "ToMaximumDepth",
"Args": { "maximumDestructuringDepth": 3 }
},
{
"Name": "ToMaximumStringLength",
"Args": { "maximumStringLength": 10 }
},
{
"Name": "ToMaximumCollectionCount",
"Args": { "maximumCollectionCount": 5 }
}
],
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "Application = 'MySample.Service'"
}
},
{
"Name": "With",
"Args": {
"filter": "MySample.Logging.CustomFilter, MySample.Service"
}
}
]
}
}
And a Logging support class like this:
static class Logging
{
internal static ILogger Logger { get; } = BuildConfiguration().CreateLogger();
private static DateTime Now { get; } = DateTime.Now;
private static string GetLogFilePath(string subsystem = null)
{
var fileNameWithoutExtenskion = Assembly.GetExecutingAssembly().Location.GetFileNameWithoutExtension();
var nowTimeStamp = Now.ToString("s").Replace(":", "_");
const string dotlog = ".log";
var logFileName = IsNullOrEmpty(subsystem)
? Join("-", $"{fileNameWithoutExtenskion}", $"{nowTimeStamp}{dotlog}")
: Join("-", $"{fileNameWithoutExtenskion}", subsystem, $"{nowTimeStamp}{dotlog}");
const string myComp = "My Comp";
return CommonApplicationData.GetFolderPath().Combine(myComp, logFileName);
}
private static ILogger CreateLogger(this IConfigurationRoot root)
{
const string errors = nameof(errors);
return new LoggerConfiguration()
.ReadFrom.Configuration(root)
.Enrich.FromLogContext()
.WriteTo.Async(a => a.File(GetLogFilePath()) /*, monitor: new MonitorConfiguration()*/)
.WriteTo.Conditional(
e => new[] { LogEventLevel.Error, LogEventLevel.Fatal }.Contains(e.Level)
, a => a.File(GetLogFilePath(errors))
)
.CreateLogger();
}
private static IConfigurationRoot BuildConfiguration()
{
var execAssyLocation = Assembly.GetExecutingAssembly().Location;
var jsonFilePath = Path.Combine(execAssyLocation.GetDirectoryName(), "appsettings.json");
return new ConfigurationBuilder()
.AddJsonFile(path: jsonFilePath, optional: false, reloadOnChange: true)
.Build();
}
private static string Combine(this string path, params string[] paths) => Path.Combine(
paths.Any() ? new string[] { path }.Concat(paths).ToArray() : new string[] { path }
);
private static string GetFileNameWithoutExtension(this string path) => Path.GetFileNameWithoutExtension(path);
private static string GetDirectoryName(this string path) => Path.GetDirectoryName(path);
private static string GetFolderPath(this Environment.SpecialFolder folder) => Environment.GetFolderPath(folder);
}
As far as I know, I've got all the requisite packages referenced.

Turns out it was an issue of my needing to reference a dev release of the Serilog.Settings.Configuration package. Then it suddenly started to work.

Related

Parse Array in Object in Array in Dart / Flutter

I have a REST Service I like to consume, but I do not know how to parse that JSON to an Object.
My JSON looks like that:
[
{
"types": {
"KEYWORD": "STRING"
},
"displaynames": {
"KEYWORD": "Keyword"
},
"rows": [
{
"KEYWORD": "Test 1"
},
{
"KEYWORD": "Test 2"
}
]
}
]
That is my object I created from that:
import 'dart:convert';
List<Todo> welcomeFromJson(String str) =>
List<Todo>.from(json.decode(str).map((x) => Todo.fromJson(x)));
String welcomeToJson(List<Todo> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Todo {
Todo({
required this.types,
required this.displaynames,
required this.rows,
});
Displaynames types;
Displaynames displaynames;
List<Displaynames> rows;
factory Todo.fromJson(Map<String, dynamic> json) => Todo(
types: Displaynames.fromJson(json["types"]),
displaynames: Displaynames.fromJson(json["displaynames"]),
rows: List<Displaynames>.from(
json["rows"].map((x) => Displaynames.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"types": types.toJson(),
"displaynames": displaynames.toJson(),
"rows": List<dynamic>.from(rows.map((x) => x.toJson())),
};
}
class Displaynames {
Displaynames({
required this.keyword,
});
String keyword;
factory Displaynames.fromJson(Map<String, dynamic> json) => Displaynames(
keyword: json["KEYWORD"],
);
Map<String, dynamic> toJson() => {
"KEYWORD": keyword,
};
}
I try Loading the JSON and Display like that by using the pull_to_refresh Package.
import 'package:flutter/material.dart';
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
import 'dart:convert';
import 'package:user_portal/model/todo.dart';
class TodoRoute extends StatefulWidget {
const TodoRoute({super.key});
#override
State<TodoRoute> createState() => _TodoRouteState();
}
class _TodoRouteState extends State<TodoRoute> {
late List<Todo> todoList = [];
final RefreshController refreshController =
RefreshController(initialRefresh: true);
Future<bool> fetchTodo() async {
const String jsonstr =
'[ { "types": { "KEYWORD": "STRING" }, "displaynames": { "KEYWORD": "Keyword" }, "rows": [ { "KEYWORD": "Test 1" }, { "KEYWORD": "Test 2" } ] }]';
todoList = (json.decode(jsonstr) as List)
.map((data) => Todo.fromJson(data))
.toList();
setState(() {});
return true;
}
#override
Widget build(context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todo'),
),
body: SmartRefresher(
controller: refreshController,
enablePullUp: true,
onRefresh: () async {
final result = await fetchTodo();
if (result) {
refreshController.refreshCompleted();
} else {
refreshController.refreshFailed();
}
},
onLoading: () async {
final result = await fetchTodo();
if (result) {
refreshController.loadComplete();
} else {
refreshController.loadFailed();
}
},
child: ListView.separated(
scrollDirection: Axis.vertical,
itemCount: todoList.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todoList[0].rows[index].keyword),
);
},
separatorBuilder: (context, index) => const Divider(),
),
),
);
}
}
But the Only Item I get is the Test 1 Item not the Test 2 Item and I do not know where to look further for that Problem.
try this way it's so easy...
add this method in your TOdo model
static List< Todo > fromList(json) {
List< Todo > tempList = [];
try {
json.forEach((element) {
tempList.add(Todo.fromJson(element));
});
return tempList;
} catch (e) {
return tempList;
}
}
change this function
Future<bool> fetchTodo() async {
const String jsonstr =
'[ { "types": { "KEYWORD": "STRING" },
"displaynames": { "KEYWORD": "Keyword" }, "rows": [ {
"KEYWORD": "Test 1" }, { "KEYWORD": "Test 2" }
]
}]';
Map data = json.decode(jsonstr);
todoList = Todo.fromList(data);
setState(() {});
return true;
}
Change your fetchTodo() to this:
Future<bool> fetchTodo() async {
const String jsonstr =
'[ { "types": { "KEYWORD": "STRING" }, "displaynames": { "KEYWORD": "Keyword" }, "rows": [ { "KEYWORD": "Test 1" }, { "KEYWORD": "Test 2" } ] }]';
todoList = welcomeFromJson(jsonstr);//<--- add this
setState(() {});
return true;
}
also change this in asdas class:
factory Todo.fromJson(Map<String, dynamic> json) => Todo(
types: Displaynames.fromJson(json["types"]),
displaynames: Displaynames.fromJson(json["displaynames"]),
rows: json["rows"] != null ? (json["rows"] as List).map((x) => Displaynames.fromJson(x)).toList():[],

JSON Transformation to required format

We are working on a Middleware platform where we are required to respond to consumer with a JSON data in a particular format.
The Data we get from south bound API is a key value pair and this needs to be mapped to an understandable format for the consumer
We tried json-path, ObjectMapper but none of them is giving us the expected result for transforming
Respnse from backend API
{
"details": [
{
"name": "x.y.z.name","value": "TR-54695"
},
{
"name": "a.b.c.standards","value": "DOCSIS"
},
{
"name": "x.x.x.hversion","value": "10"
},
{
"name": "x.x.x.sversion","value": "9.1.116V"
},
{
"name": "x.x.x.uptime","value": "8000"
},
{
"name": "x.x.x.accessallowed","value": "true"
},
]
}
To be transformed to
{
"myData": {
"myInfo": {
"productClass": "TR-54695",
"supportedStandards": "DOCSIS",
"hardwareVersion": "10",
"softwareVersion": "9.1.116V",
"modemMacAddress": "",
"upTime": "8000",
"modemNetworkAccessAllowed": true
}
}
}
Do not like manual work, so here generated demo using 2 functions.
Mind ticking accept button under voting in case you like some answer.
function translate(src, mapping) {
var dst = { "myData": { "myInfo": { "modemMacAddress": "" } } }
//in case order matters:
dst = { "myData": { "myInfo": { "productClass": "", "supportedStandards": "", "hardwareVersion": "", "softwareVersion": "", "modemMacAddress": "", "upTime": "", "modemNetworkAccessAllowed": undefined } } }
var trueFalse = { "false": false, "true": true };
src = src.details;
for (var i = 0; i < src.length; i++) {
dst.myData.myInfo[mapping[src[i].name]] = trueFalse[src[i].value] || src[i].value;
}
return dst;
}
function generateMapping(src, dst) {
src = src.details;
var backLinks = {}, rename2 = {};
for (var i = 0; i < src.length; i++) {
backLinks[src[i].value] = src[i].name;
}
dst = dst.myData.myInfo;
for (var i in dst) {
rename2[backLinks[dst[i]]] = i;
}
return rename2;
}
var src = {
"details": [
{ "name": "x.y.z.name", "value": "TR-54695" },
{ "name": "a.b.c.standards", "value": "DOCSIS" },
{ "name": "x.x.x.hversion", "value": "10" },
{ "name": "x.x.x.sversion", "value": "9.1.116V" },
{ "name": "x.x.x.uptime", "value": "8000" },
{ "name": "x.x.x.accessallowed", "value": "true" },
]
}
var dst = {
"myData": {
"myInfo": {
"productClass": "TR-54695",
"supportedStandards": "DOCSIS",
"hardwareVersion": "10",
"softwareVersion": "9.1.116V",
"modemMacAddress": "",
"upTime": "8000",
"modemNetworkAccessAllowed": true
}
}
}
var mapping = generateMapping(src, dst);
// var mapping = {
// "x.y.z.name": "productClass",
// "a.b.c.standards": "supportedStandards",
// "x.x.x.hversion": "hardwareVersion",
// "x.x.x.sversion": "softwareVersion",
// "undefined": "modemMacAddress",
// "x.x.x.uptime": "upTime",
// "x.x.x.accessallowed": "modemNetworkAccessAllowed"
// }
var result = translate(src, mapping);
console.log(JSON.stringify(result, null, 2));
console.log(JSON.stringify(mapping, null, 2));
You can use below code and use codesandbox link (check console output ) for exact response and this link for key:value pair.
let response = {
details: [
{
name: "x.y.z.name",
value: "TR-54695"
},
{
name: "a.b.c.standards",
value: "DOCSIS"
},
{
name: "x.x.x.hversion",
value: "10"
},
{
name: "x.x.x.sversion",
value: "9.1.116V"
},
{
name: "x.x.x.uptime",
value: "8000"
},
{
name: "x.x.x.accessallowed",
value: "true"
}
]
};
// convert function for key value pair
function convertResponse(responseData) {
let output = { myData: { myInfo: {} } };
let outputRef = output.myData.myInfo;
responseData.forEach(element => {
outputRef[element.name] = element.value
});
return output;
}
// OR convert Function for getting exact same output
function convertResponse(responseData) {
let output = { myData: { myInfo: {} } };
let outputRef = output.myData.myInfo;
responseData.forEach(element => {
if (element.name === "x.y.z.name") {
outputRef.productClass = element.value;
} else if (element.name === "a.b.c.standards") {
outputRef.supportedStandards = element.value;
} else if (element.name === "x.x.x.hversion") {
outputRef.hardwareVersion = element.value;
} else if (element.name === "x.x.x.sversion") {
outputRef.softwareVersion = element.value;
} else if (element.name === "x.x.x.uptime") {
outputRef.upTime = element.value;
} else if (element.name === "x.x.x.accessallowed") {
outputRef.modemNetworkAccessAllowed = element.value;
}
});
return output;
}
//Function Call
console.log(convertResponse(response.details));

Merge the two different JSON using node JS

I have two requests that return their data as JSON using NodeJS Seriate.
The first response is:
{
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schem,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014"
}
}
}
}
]
}
The second response is:
{
"statusCode": 200,
"body": {
"errors": [],
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]
}
}
I want to merge the two responses, that would have the following structure:
{
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014",
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]
}
}
}
}
]
}
I searched and found several methods of joining or extending two JSON objects but nothing similar to that.
How can I achieve this?
My Actual Code is,
exports.getIssues = function(req, res) {
console.log(filename + '>>get Issues>>');
var response = {
status : Boolean,
message : String,
data : String
};
var request = require('request');
var username = const.username ;
var password = const.password ;
var options = {
url : 'https://computenext.atlassian.net/rest/api/2/search?jql=status+%3D+Resolved+ORDER+BY+updated',
auth : {
username : username,
password : password
}
};
request( options, function(error, obj) {
if (error) {
response.message = appmsg.DATA_NT_FOUND;
response.status = false;
response.data = obj;
res.send(response);
} else {
response.message = appmsg.DATA_FOUND;
response.status = true;
response.data = JSON.parse(obj.body);
//res.send(response);
var issueKey = response.data.issues;
// var keyData = issueKey[0].key;
// console.log(response.data.issues);
// console.log(keyData);
var output = [];
for(var i = 0; i < issueKey.length; i++) {
var issue = issueKey[i].key;
//var key = [];
//key.push(issue);
console.log(issue);
var respon = {
status : Boolean,
message : String,
data : String
};
var request = require('request'),
username = const.username ,
password = const.username ,
url = "https://computenext.atlassian.net/rest/api/2/issue/" + issue,
auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
//console.log(url);
request({url : url,headers : {"Authorization" : auth}}, function(err, object){
if (object) {
var info = object;
output.push(info); // this is not working as ouput is undefined at this point
//var pout = JSON.parse(output);
//console.log(info);
console.log("==============================================================================");
//console.log(output);
console.log("******************************************************************************");
if(issueKey.length === output.length){
respon.message = appmsg.DATA_FOUND;
respon.status = true;
respon.data = output;
//console.log(output);
//res.send(respon);
var id = issueKey[0].id;
console.log(id);
var commitout = [];
for(var i = 0; i < issueKey.length; i++) {
var commits = issueKey[i].id;
console.log(commits);
var request = require('request'),
username = const.username ,
password = const.password ,
url = "https://computenext.atlassian.net/rest/dev-status/1.0/issue/detail?issueId=" + commits + "&applicationType=stash&dataType=repository",
auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
//console.log(url);
var test = [];
request({url : url,headers : {"Authorization" : auth}}, function(err, obj1){
if (obj1) {
var info1 = obj1.body;
commitout.push(info1);
if(issueKey.length === commitout.length){
respon.message = appmsg.DATA_FOUND;
respon.status = true;
respon.data = commitout;
// console.log(commitout);
//var test = merge(output, commitout);
var text = output.body;
var resultdone = output;
resultdone.data = resultdone + commitout.body;
console.log(resultdone.data);
res.send(resultdone.data);
}
}
});
}
}
}
});
}
}
});
};
How can i merge the two arrays? in one response. That is my question..
Never mainpulate the string of JSON directly. Parse it first.
const firstRes = JSON.parse(firstResJson);
const secondRes = JSON.prase(secondResJson);
Now, it's a bit unclear what you want to do, and why you want to do it, but try this:
firstRes.data.body.fields.parent.detail = secondRes.body.detail;
Then, you'll find your combined data in firstRes. To get it back to JSON:
JSON.stringify(firstRes);
var obj1 = {
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schem,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014"
}
}
}
}
]};
var obj2 = {
"statusCode": 200,
"body": {
"errors": [],
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]}
}
obj1.data.forEach(function(item, index){
item.body.fields.parent.detail = r.body.detail[index];
});
console.log(obj1);
var result1 =
{
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schem,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014"
}
}
}
}
]
}
var text = result1.data[0].body;
var result2 =
{
"statusCode": 200,
"body": {
"errors": [],
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]
}
};
var resultdone = result1;
resultdone.data[0].body.fields.parent= result2.body.detail;

Observable from a RESTful paged collection

On one hand, I have a RESTful HAL HATEOAS collection which looks like this :
{
"page": 1,
"limit": 10,
"pages": 18,
"total": 174,
"_links": {
"self": { "href": "/users?page=1&limit=10" },
"first": { "href": "/users?page=1&limit=10" },
"last": { "href": "/users?page=18&limit=10" },
"next": { "href": "/users?page=2&limit=10" }
},
"_embedded": {
"users": [
{
"name": "bob",
"_links": { "self": { "href": "/users/1" } }
},
...
]
}
}
On the other hand, I have an Angular 2 app.
public getUsers(uri: string = this.baseURI): Observable<User> {
return this.http.get(uri)
.map(res => res.json()._embedded.users as User[])
.flatMap(d => d) // Transform the flux of arrays in flux of users
.catch(this.handleError);
} // Get only the 10th first users
What I'm trying to do have an observable of Users which will append data while _links.next != null
Modified service
public getUsers(uri: string = this.baseURI): Observable<User> {
return this.http.get(uri)
.do(res => {
const uri = JSON.parse(res._body)._links.next.href;
this.nextUri = uri ? uri : null;
})
.map(res => res.json()._embedded.users as User[])
.flatMap(d => d) // Transform the flux of arrays in flux of users
.catch(this.handleError);
}
Recursive function
loadAll(uri: string) {
read(uri)
.subscribe(
user => {
this.stockedUsers.push(user);
},
error => console.log(error),
() => {
if (this.nextUri) {
this.loadAll(this.nextUri);
}
}
);
}
Does someone know how to achieve this properly ?
I want to keep thes advantages of the RxJS flux.
UPDATE/ANSWER
Silly me ! I think I answered myself. Maybe this will help others :
public read(uri: string = this.baseURI): Observable<User> {
return Observable.create(observer => this.iteratePages(observer, uri));
}
private iteratePages(observer: Observer<User>, uri): void {
if (uri == null) { return observer.complete(); }
this.http.get(uri).subscribe(res => {
const data = res.json();
for (const user of data._embedded.users) {
observer.next(user as User);
}
const nextUri = (data._links && data._links.next) ? data._links.next.href : null;
this.iteratePages(observer, nextUri);
});
}

how can i get string json in angular2

in my angular2 component
keyword_test={};
getData() {
this.service.getData()
.subscribe(
data => {
this.keyword_test = data
console.log(data);
console.log(this.keyword_test);
});
}
console.log(data) and console.log(this.keyword_test) print right data like this
{
"caption": "folder0",
"type": "folder",
"subnodes": [
{
"caption": "folder1",
"type": "folder",
"subnodes": [
{
"caption": "keyword1",
"type": "keyword",
"search_filter_expression": "sfe1"
},
{
"caption": "keyword2",
"type": "keyword",
"search_filter_expression": "sfe2"
}
]
},
{
"caption": "folder2",
"type": "folder",
"subnodes": [
{
"caption": "keyword3",
"type": "keyword",
"search_filter_expression": "sfe3"
},
{
"caption": "keyword4",
"type": "keyword",
"search_filter_expression": "sfe4"
}
]
}
]
}
but in my ngOnInit
ngOnInit() {
this.getData();
console.log(this.keyword_test);
}
despite the this.getdata(), this.keyword_test print "Object {}" i think none object.
Is the keyword_test initialized incorrectly?
when i print console.log(typeof data) in getData function, result is string...
I did change it to json in service, but I do not know why.
++and this is my service
#Injectable()
export class keywordService {
private API_URI: string = 'MYAPIURL';
constructor(private http: Http) {
}
getData() {
return this.http.get(this.API_URI, {body: ""})
.map(res => {res.json();
});
}
}
ngOnInit() {
this.getData(); // this execute but data arrives with call back
console.log(this.keyword_test); //this execute before data has arrived and thats why it is not printing the result from success call
}
Correct way
this.service.getData()
.subscribe(
data => {
this.keyword_test = data
console.log(data);
console.log(this.keyword_test);
});