Serilog Azure EventHub Sink output template json - json

So, I am battling and trying to figure this out.
I have Serilog and using EventHub to log errors.
It took a while to find but I needed it to be serialized into JSON so I used this:
logger = new LoggerConfiguration().WriteTo.Sink(new AzureEventHubSink(eventHubClient, new JsonFormatter()))
.CreateLogger();
Great. Now, when I write the exception:
logger.Error(ex, "An Error Occurred");
It writes it BUT the exception is written in 1 field (big long strong).
Is there a way to tell SeriLog to write each property of the exception in its own field (think of it as a SQL table with fields)?
How about changing the outputTemplate but still using JsonFormatter, as there is no overload to accept the output template?
I am using Stream Analytics to do some querying and it makes it better (MUCH better) to have each exception property as its own field column rather than just 1 field with the entire JSON string in there, and I need to do cross joins on another data source.
Thank you.

Seems the only way is to inherit from JsonFormatter and then override the WriteException method and write the Property in question....
WriteJsonProperty("ClassName", exception.GetType(), ref delim, output);
WriteJsonProperty("Message", exception.Message, ref delim, output);

Related

Knime MongoDBReader read an Object with an array in it

I tried to read an Object with the MongoDB reader and I always get the following error message:
"ERROR MongoDB Reader 0:19 Execute failed: Invalid type 19 for field value".
The typ of the field value is an Array.
I want to read the object and want to get the array inside the Object.
Here you can see the MongoDB with the Object I want to read.
“Type 19” indicates a Decimal128 type, see this link.
I’d assume that this type is just not supported by the MongoDB nodes (note how above link says “New in version 3.4.”).
[personal opinion] The KNIME MongoDB nodes are not very well maintained. Beside some basic “hello world” attempts I wasn’t able to use them for any of my real-world usage scenarios.

Getting No converter found error

Query(value = "SELECT * FROM test where id = :key", nativeQuery=true)
public User findById(#Param("key") String key);
The above query working is fine.
Query(value = "SELECT * FROM test where id = :key", nativeQuery=true)
public localhost._8080.ws.User findId(#Param("key") String key);
But the above query getting the error as below :
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [localhost._8080.ws.User]
SOAP XSD created auto generated classes and expecting output localhost._8080.ws.User type due to that getting error.
Please suggest on this error.
Spring Data JPA is not intended to map arbitrary results of SQL statements to arbitrary objects.
It maps results into DTOs or projections.
Most likely you generated class has properties it doesn't know how to handle.
Probably the most sensible way to solve this is to have the repository return something it can handle (User or a Map should work) and create your desired type from there using your own code or a library intended for such conversion.
Dozer seems a popular choice for that.

TypeScript types serialisation/deserialization in localstorage

I have a Typescript app. I use the localstorage for development purpose to store my objects and I have the problem at the deserialization.
I have an object meeting of type MeetingModel:
export interface MeetingModel {
date: moment.Moment; // from the library momentjs
}
I store this object in the localStorage using JSON.stringify(meeting).
I suppose that stringify call moment.toJson(), that returns an iso string, hence the value stored is: {"date":"2016-12-26T15:03:54.586Z"}.
When I retrieve this object, I do:
const stored = window.localStorage.getItem("meeting");
const meeting: MeetingModel = JSON.parse(stored);
The problem is: meeting.date contains a string instead of a moment !
So, first I'm wondering why TypeScript let this happen ? Why can I assign a string value instead of a Moment and the compiler agree ?
Second, how can I restore my objects from plain JSON objects (aka strings) into Typescript types ?
I can create a factory of course, but when my object database will grow up it will be a pain in the *** to do all this work.
Maybe there is a solution for better storing in the local storage in the first place?
Thank you
1) TypeScript is optionally typed. That means there are ways around the strictness of the type system. The any type allows you to do dynamic typing. This can come in very handy if you know what you are doing, but of course you can also shoot yourself in the foot.
This code will compile:
var x: string = <any> 1;
What is happening here is that the number 1 is casted to any, which to TypeScript means it will just assume you as a developer know what it is and how you to use it. Since the any type is then assigned to a string TypeScript is absolutely fine with it, even though you are likely to get errors during run-time, just like when you make a mistake when coding JavaScript.
Of course this is by design. TypeScript types only exist during compile time. What kind of string you put in JSON.parse is unknowable to TypeScript, because the input string only exists during run-time and can be anything. Hence the any type. TypeScript does offer so-called type guards. Type guards are bits of code that are understood during compile-time as well as run-time, but that is beyond the scope of your question (Google it if you're interested).
2) Serializing and deserializing data is usually not as simple as calling JSON.stringify and JSON.parse. Most type information is lost to JSON and typically the way you want to store objects (in memory) during run-time is very different from the way you want to store them for transfer or storage (in memory, on disk, or any other medium). For instance, during run-time you might need lookup tables, user/session state, private fields, library specific properties, while in storage you might want version numbers, timestamps, metadata, different types of normalization, etc. You can JSON.stringify anything you want in JavaScript land, but that does necessarily mean it is a good idea. You might want to design how you actually store data. For example, an iso string looks pretty, but takes a lot of bytes. If you have just a few that does not matter, but when you are transferring millions a second you might want to consider another format.
My advise to you would be to define interfaces for the objects you want to save and like moment create a .toJson method on your model object, which will return the DTO (Data Transfer Object) that you can simply serialize with JSON.stringify. Then on the way back you cast the any output of JSON.parse to your DTO and then convert it back to your model with a factory function or constructor of your creation. That might seem like a lot of boilerplate, but in my experience it is totally worth it, because now you are in control of what gets stored and that gives you a lot of flexility to change your model without getting deserialization problems.
Good luck!
You could use the reviver feature of JSON.parse to convert the string back to a moment:
JSON.parse(input, (key, value) => {
if (key == "date") {
return parseStringAsMoment(value);
} else {
return value;
});
Check browser support for reviver, though, as it's not the same as basic JSON.parse

Grails, create domain object from json-string with has-many relation

I'm trying to parse a grails parameter map to a Json String, and then back to a parameter map. (For saving html form entries with constraint-violations)
Everything is fine as long as there is no hasMany relationship in the parameter-map.
I'm using
fc.parameter = params as JSON
to save the params as JSON String.
Later I'm trying to rebuild the parameter map and create a new Domain-Object with it:
new Foo(JSON.parse(fc.parameter))
Everything is fine using only 1:1 relationships (states).
[states:2, listSize:50, name:TestFilter]
But when I try to rebuild a params-map with multi-select values (states)
[states:[1,2], listSize:50, name:TestFilter]
I'm getting this IllegalStateException:
Failed to convert property value of type org.codehaus.groovy.grails.web.json.JSONArray to required type java.util.Set for property states; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [de.gotosec.approve.State] for property states[0]: no matching editors or conversion strategy found
I tried to use this, but without success:
JSON.use("deep") {
new Foo(JSON.parse(fc.parameter))
}
You can use JsonSlurper instead of the converters.JSON of grails, it maps JSON objects to Groovy Maps. I think this link also might help you.
Edit: Now, if the problem is binding the params map to your domain, you should try using bindData() method, like:
bindData(foo, params)
Note that this straightforward use is only if you're calling bindData inside a controller.
What seems to be happening in your case is that Grails is trying to bind a concrete type of List (ArrayList in the case of JsonSlurper and JSONArray in the case of converters.JSON) into a Set of properties (which is the default data structure for one-to-many associations). I would have to take a look at your code to confirm that. But, as you did substitute states: [1,2] for a method of your app, try another test to confirm this hypothesis. Change:
states:[1,2]
for
states:[1,2] as Set
If this is really the problem and not even bindData() works, take a look at this for a harder way to make it work using object marshalling and converters.JSON. I don't know if it's practical for you to use it in your project, but it sure works nicely ;)

Choose deep or shallow JSON serialization in Grails

Is there a way to easily specify whether to convert an object as JSON in a deep or shallow manner? I know you can configure the grails.converters.JSON utility in the Config.groovy file by specifying something like the following:
grails.converters.json.default.deep = true
but when I convert certain objects, I don't want to deep convert.
I also saw that somebody recommended using JSON.use("deep"), but I get the following error:
Error 2012-03-04 00:39:13,673 ["http-bio-8080"-exec-1] ERROR errors.GrailsExceptionResolver - IllegalAccessException occurred when processing request: [GET] /Quaffic/home/json
Class org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller can not access a member of class org.joda.time.tz.DateTimeZoneBuilder$PrecalculatedZone with modifiers "public". Stacktrace follows:
Message: Class org.codehaus.groovy.grails.web.converters.marshaller.json.GenericJavaBeanMarshaller can not access a member of class org.joda.time.tz.DateTimeZoneBuilder$PrecalculatedZone with modifiers "public"
Line | Method
->> 198 | value in grails.converters.JSON
It seems like it could be a joda.time error, but this doesn't happen when I just use the plain Config.groovy technique. Kind of confusing...
Any help would be great!
My solution was to not rely on deep/shallow json generation. I created a map, inserted elements, and serialized that. Probably not the best practice, but it gets the job done.