How to include additional properties when using structured logging with NLog? - vb.net

I know you can do this:
_Logger.Info("This is my message: {MessageId}. And here's an explanation: {expl}", messageId, expl)
which will insert the value of messageId and expl into the message like String.Format, based on their order in the string.
Unfortunately, I want to add extra properties beyond those from the structured message logging, so I'm using LogEventInfo:
Dim ev as New LogEventInfo(LogLevel.Info, "", "This is my message: {MessageId}")
ev.Properties{"EventId"}=eventId
_Logger.Log(ev)
Are there other ways for adding additional properties in an elegant way?

I think you're looking for WithProperty to add properties which aren't in the message.
Example:
_Logger.WithProperty("EventId", eventId)
.Info("This is my message: {MessageId}. And here's an explanation: {expl}", messageId, expl)
See also: https://github.com/NLog/NLog/wiki/Context#logevent-properties

Related

validating multiple input query params in Mule 4

I am using Mule 4.4 community edition
I have a GET endpoint with 4 query params:
empId ( mandatory )
collegeId ( mandatory )
subject ( either subject or score is required )
score ( either subject or score is required )
what is the best way to be doing these validations ?
Here is what I have tried but am not satisfied with the outcome ...
Validating 'empId' and 'collegeId' through Open API spec ( required attribute )
parameters:
- name: empId
in: query
description: The web user account
required: true
schema:
type: string
- name: collegeId
in: query
description: The web organisation
required: true
However if I simply pass an empty string against these , no validation is triggered ....
Tried using pattern such as :
pattern: "^[A-Za-z0-9]+$"
while this does prevent empty / null strings the error message is not satisfactory :
Invalid value ' ' for uri parameter empId.
string [ ] does not match pattern ^[A-Za-z0-9]+$
Question: Can I override the error message in Open API spec to make it something easier on the eyes ?
Now on to 'subject' and 'score' , atleast one of these should be non null or empty
Did not find anything except this link here
How do we enforce atleast one of the two has a non null / empty value ( via Open api spec 3.0.1 )
So I thought I will hand craft validation , using validators but they seem quite clunky
ex - for a simple check like 'not null or empty' have to use two validators .....
<flow name="get:employee-search" >
<validation:any doc:name="Any" >
<validation:is-not-null doc:name="Is subject not null" value="#[attributes.queryParams['subject']]" message="${validation.subject}" />
<validation:is-not-null doc:name="Is score not null" value="#[attributes.queryParams['score']]" message="${validation.score}" />
<validation:is-not-blank-string doc:name="Is subject not blank string" value="#[attributes.queryParams['subject']]" message="${validation.subject}"/>
<validation:is-not-blank-string doc:name="Is score not blank string" value="#[attributes.queryParams['score']]" message="${validation.score}"/>
</validation:any>
also if both fields are not sent then the error message for both validators shows up
Question:
should I write a groovy script to perform these simple validations
Just wanted to know if that is the best approach or something better ?
I do not think you can customize the error message solely via Open API Specs, However when you generate the flows in your application, it will create error handlers too for APIKIT validations. You can write a transform message within the bad request error handler to modify the response by checking the error message.
Now for the Validation part, you do not need to check for validation:is-not-null if you are checking validation:is-not-blank-string as the later will also check if the string is Null. Also you will have to merge the remaining two validators as well, otherwise, it will fail if the subject is empty even though the score is passed. For handling this you can use either validation:is-false or validation:all Scope.
With validation:all you will wrap the two validation:is-not-blank-string in a single scope, and it will fail only if both of the validation fails.
With the validation:is-false you can write custom weave expression in the module, that returns true if both the fields are blank. This will fail this validation (since it is not false) and you can customize the error message. Something like this
<validation:is-false doc:name="Is false"
doc:id="c62a27a4-d030-4f72-9610-eacbb74dd593"
expression="#[isBlank(attributes.queryParams.score) and isBlank(attributes.queryParams.subject)]"
message="Both Score and Subject can not be empty" />

How to update a Podio category using PHP API

I'm using a webhook to kick off a series of PHP scripts that take advantage of the Podio PHP API. I've tried using several different API calls but haven't been able to sort this out. This is a test file I'm using so the actual logic of what its doing doesn't make much sense. When I run the code below I get the error.
PHP Fatal error: Uncaught PodioBadRequestError: "Invalid value "status" (string): Not a valid option"
Request URL: http://api.podio.com/item/<removed>/value/<removed>
Stack Trace:
/data/www/default/contracts/lib/podio-php-master/lib/Podio.php(357):
Podio::request('PUT', '/item/<removed>...', Array)
/data/www/default/contracts/lib/podio-php-master/models/PodioItemField.php(55): Podio::put('/item/<removed>...', Array)
/data/www/default/contracts/test-category.php(25):
PodioItemField::update(<removed>, <removed>, Array, Array)
{main}
thrown in /data/www/default/contracts/lib/podio-php-master/lib/Podio.php on line 291`
Here is my code:
//dummy item_id
$item_id = 123456789;
//dummy field_id
$field_id = 987654321;
//Get the category field value
$item = PodioItem::get_field_value($item_id, $field_id);
//Create a variable with the text of the selected category option for validation
$button_value = $item[0]['value']['text'];
//Print the text of the selected option
print $button_value;
//Now that I have validated the current selection I want to change it
//These are the names of the attributes for my category
$my_attributes = array("status", "text", "id", "color");
//These are the values I want to update them to
$my_options = array("active","Generated",21,"DCEBD8");
//This should update the record in podio with the new values
PodioItemField::update($item_id, $field_id, $my_attributes, $my_options);
I reviewed all of the examples in the documentation but I feel like I'm missing something simple. Is anyone familiar with this that can tell me what I'm doing wrong? I've tried to comment the code to make it clear what I expect to be happing on each line but I can definitely clarify more if needed.
You are passing the attributes in the wrong method. To update the Category field you just pass the id of the option that you want to change in an array. So the $my_attributes array must be like,
$my_attributes = array(21);//id of the category option
And the $my_options array should like this,
$my_options = array('silent' => true, 'hook' => false);
This should update the item in Podio with the new values,
PodioItemField::update($item_id, $field_id, $my_attributes, $my_options);

PropertyType search problems with RESO API

I am using connect-mls RESO API and I am having a problem forming the query to search for via PropertyType.
http://odata.reso.org/RESO/OData/Property?$filter=/PropertyType/Name eq "Residential"
The above query keeps coming up with malformed URI.
I also run into a problem is if try to filter on the PropertyType field directly via $filter=(PropertyType eq 'Residental') or $filter=(PropertyType eq 'DE').
I get the following error message:
"message": "StatusCodeError: 400 - {\"error\":{\"code\":null,\"message\":\"The types 'ODataService.PropertyType' and 'Edm.String' are not compatible.\"}}"
Also looked at values in the data dictionary because it seems property type is a enum but have not had any success in any of the formats.
http://ddwiki.reso.org/display/DDW16/Property+Type+Summary
Appreciate any guidance on this.
I was able to find the answer from another source. For the enums they are in a format of ODataService.PropertyType'DE'. A proper API call example is listed below.
https://connectmls-api.mredllc.com/reso/odata/Property?$filter=PropertyType eq ODataService.PropertyType'DE'
For more detailed information on how to properly construct these types of queries, you can look at http://www.odata.org/documentation/

Retrieve a document class-description symbolicName without fetching

I'm triying to retrieve a ClassDescription symbolicName of an IDocument object. It seems that i have to fetch its ClassDescription even if I just want the symbolicName.
Is there a way to do it ? I just want to avoid doing a fetch for every browsed document...
(Also IDocument.GetClassName doesn't help, it returns "Document")
I finally found a way, by making an SQL SELECT request retrieving the classDescription ID (which is not the symbolicName ID, but rather an "internal" one) :
Select This, d.Id, d.ClassDescription
From Document d
where d.Id = ID
It seems to be lighter than a line like document.fetch(classDescription) (pseudo call) cause it should just retrieves the ID.
I thought it worth mentioning a problem regarding the accepted answer.
There are times that doing a query would be "lighter" however I believe you are missing something involving fetching a document.
FileNet's fetchInstance command can take in a PropertyFilter.
In your case you could do something along the lines of:
PropertyFilter pf = new PropertyFilter();
pf.AddIncludeProperty(new FilterElement(null, null, null, "ClassDescription", null));
doc = Factory.Document.FetchInstance(os, new Id("doc.ID()"), pf);
You would probably want to look at your original fetch of this document and make sure to specify the full list of property filters at that point.
See Working With Documents

Send keys with modifiers in Capybara/Poltergeist

So Poltergeist send_keys let you do this:
element = find('input#id')
element.native.send_key('String')
element.native.send_keys('H', 'elo', :Left, 'l') # => 'Hello'
element.native.send_key(:Enter) # triggers Enter key
I'm looking to send key combinations like:
Control-A
Alt-C
Can't find any references or had any success with various attempts.
Suggestions?
According to Issue #420 and the accompanying commit, you can do it in the following way:
element.native.send_keys('H', [:Shift, 'elo'], :Left, 'l')
element.native.send_key([:Ctrl, :Enter])
You can define multiple modifiers like this:
[:Ctrl, :Shift, "aaa"]
There is currently no release containing that change (last one is 1.6.0), so you will need to build it yourself.