NLog JSON structred event-property - json

This is my NLog configuration:
<layout type="JsonLayout">
<attribute name="businessProcessName" layout="${event-properties:rawMessage:item=BusinessProcess}" />
<attribute name="businessDepartmentName" layout="${event-properties:rawMessage:item=BusinessDepartment}" />
<attribute name="logType" layout="${event-properties:rawMessage:item=logType}" />
<attribute name="queueName" layout="${event-properties:rawMessage:item=QueueName}" />
<attribute name="data" layout="${event-properties:rawMessage:item=LogF_AllTransactionData}" />
</layout>
Which is giving me the following result:
{ "businessProcessName": "ACME", "businessDepartmentName": "Lior", "logType": "User", "queueName": "LoggingTest", "data": "{\r\n \"ExecuterJobGUID\": \"Studio_05fe3a0e-dc3b-4635-a521-5fe450cdb13e\",\r\n \"LogF_TransactionReference\": \"MyTransaction\",\r\n \"LogF_StartTransactionTime\": \"08\/02\/2022 17:11:33\",\r\n \"LogF_TransactionId\": \"23031\",\r\n \"LogF_QueueName\": \"LoggingTest\",\r\n \"LogF_QueueDefinitionId\": 545,\r\n \"LogF_SpecificContent\": {\r\n \"FirstName\": \"Lior\",\r\n \"LastName\": \"Hen\",\r\n \"BirthDate\": \"1989-12-03T00:00:00Z\"\r\n },\r\n \"LogF_Progress\": \"\",\r\n \"LogF_RetryNo\": 0,\r\n \"Gender\": \"Male\",\r\n \"City\": \"Ashdod\"\r\n}" }
I have two questions please:
How can I bring 'data' as Json and not as string?
How can I bring a single key from 'data', such as 'LogF_TransactionReference'?
Thank you!

If you know that the LogEvent-Property contains valid JSON, then you can specify encode="false":
<attribute name="data" layout="${event-properties:item=LogF_AllTransactionData}" encode="false" />
Then NLog will not encode/escape the LogEvent-Property-Value as JSON-string-property.
NLog ${event-properties} has the objectpath-option, but it requires that you provide the original object, instead of having serialized to JSON upfront.
<attribute name="data_id" layout="${event-properties:item=LogF_AllTransactionData:objectpath=Id}" />
<attribute name="data" layout="${event-properties:item=LogF_AllTransactionData:format=#}" encode="false" />
Alternative approach would be to implement custom-layout-renderer that parses the JSON-Object and output the wanted property. But it has a performance penalty.
See also: https://github.com/NLog/NLog/wiki/How-to-use-structured-logging

Related

How to get specific columns using fetchXML Query

I have created a report for weekly comment but everytime if i add comment and run report its coming with new column.
for example first time i need 4 columns for weekly report and its generating correctly but if we add comment and run report then it will come with 5 column for weekly comment and if we will add 1 more comment then it will come with 6 column for weekly comment, and so on.Any help will be appreciated
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="_projectcontrolsheet">
<attribute name="_supportstartfrom" />
<attribute name="_supportendson" />
<attribute name="_warrantydescription" />
<attribute name="_penaltydeadline" />
<attribute name="_ispenaltyavoided" />
<attribute name="_penaltyclause" />
<attribute name="_isanyescalationraised" />
<attribute name="_escalationraisedto" />
<attribute name="_escalationdescription" />
<attribute name="_istrainingrequired" />
<attribute name="_projectcontrolsheetid" />
<attribute name="_contactpersonnumber" />
<order attribute="projectnumber" descending="false" />
<link-entity name="pcsweeklycomments" from="weeklycommentsid" to="projectcontrolsheetid" visible="false" alias="aj" link-type="outer">
<attribute name="weeklycommentsid" />
<attribute name="name" />
<attribute name="createdby" />
<attribute name="createdon" />
<attribute name="weeklycommentdescription" />
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</link-entity>
</entity>
</fetch>
Following are Text Box Properties in Weekly Comments column
=IIf(ISNOTHING(Fields!aj_createdon.Value), "-", "Comment Date:" +Fields!aj_createdon.Value+ "<br/>Comment by : " +Fields!aj_createdby.Value+"<br />Comment Summary:" +Fields!aj_abn_name.Value+ "<br/>Comment Description : "+Fields!aj_abn_weeklycommentdescription.Value )
and i am Using Matrix

Return parent record along with all child records using Fetch XML

I want to return one parent record (Quote) along with all of its child records (Quote Details + linked entity Product) for use in a report using Fetch XML. I am using the Parent Report-Sub Report structure currently, but I need to access data that is stored on the Product in the Parent report.
I have attempted to create a Fetch XML query that fits this scenario, but I have only been able to write a query that returns the pre-filtered Quote header but all Quote Details regardless of which quote it belongs to.
The current Parent Report Fetch XML:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="quote" enableprefiltering="1" prefilterparametername="CRM_FilteredQuote">
<attribute name="name" />
<attribute name="customerid" />
<attribute name="statecode" />
<attribute name="totalamount" />
<attribute name="discountpercentage" />
<attribute name="description" />
<attribute name="new_productsubgroupid" />
<attribute name="new_masterproductgroupid" />
<attribute name="quotenumber" />
<attribute name="ownerid" />
<attribute name="createdon" />
<attribute name="quoteid" />
<attribute name="effectiveto" />
<attribute name="effectivefrom" />
<order attribute="quotenumber" descending="true" />
</entity>
</fetch>
The current Sub Report Fetch XML:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="quotedetail">
<attribute name="productid" />
<attribute name="productdescription" />
<attribute name="priceperunit" />
<attribute name="quantity" />
<attribute name="extendedamount" />
<attribute name="quotedetailid" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="quoteid" operator="eq" uitype="quote" value="#QuoteId" />
</filter>
<link-entity name="product" alias="product" to="productid" from="productid" link-type="outer" visible="false">
<attribute name="price" />
</link-entity>
</entity>
</fetch>
My attempt at a combined query (returns a single Quote, but all Quote Details, regardless of parent):
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="quote" enableprefiltering="1" prefilterparametername="CRM_FilteredQuote" >
<attribute name="name" />
<attribute name="customerid" />
<attribute name="statecode" />
<attribute name="totalamount" />
<attribute name="discountpercentage" />
<attribute name="description" />
<attribute name="new_productsubgroupid" />
<attribute name="new_masterproductgroupid" />
<attribute name="quotenumber" />
<attribute name="ownerid" />
<attribute name="createdon" />
<attribute name="quoteid" />
<attribute name="effectiveto" />
<attribute name="effectivefrom" />
<order attribute="quotenumber" descending="true" />
<link-entity name="quotedetail" alias="quoteProduct" to="quoteid" from="quoteid" link-type="outer" enableprefiltering="1" prefilterparametername="CRM_FilteredQuote" >
<attribute name="productid" />
<attribute name="productdescription" />
<attribute name="priceperunit" />
<attribute name="quantity" />
<attribute name="extendedamount" />
<attribute name="quotedetailid" />
<order attribute="productid" descending="false" />
<link-entity name="product" alias="product" to="productid" from="productid" link-type="outer" visible="false" >
<attribute name="price" />
<attribute name="new_submittleurl" />
</link-entity>
</link-entity>
</entity>
</fetch>
Try below query,
What I changed was link-type=“inner”
Previously you used outer and hence it returned you all the quote details which were not even linked and same with product details.
Let me know if this works for you.
You can try this fetchxml in xrmtoolbox plugin fetchxmlbuilder as well.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="quote" enableprefiltering="1" prefilterparametername="CRM_FilteredQuote" >
<attribute name="name" />
<attribute name="customerid" />
<attribute name="statecode" />
<attribute name="totalamount" />
<attribute name="discountpercentage" />
<attribute name="description" />
<attribute name="new_productsubgroupid" />
<attribute name="new_masterproductgroupid" />
<attribute name="quotenumber" />
<attribute name="ownerid" />
<attribute name="createdon" />
<attribute name="quoteid" />
<attribute name="effectiveto" />
<attribute name="effectivefrom" />
<order attribute="quotenumber" descending="true" />
<link-entity name="quotedetail" alias="quoteProduct" to="quoteid" from="quoteid" intersect="true" enableprefiltering="1" prefilterparametername="CRM_FilteredQuote" >
<attribute name="productid" />
<attribute name="productdescription" />
<attribute name="priceperunit" />
<attribute name="quantity" />
<attribute name="extendedamount" />
<attribute name="quotedetailid" />
<order attribute="productid" descending="false" />
<link-entity name="product" alias="product" to="productid" from="productid" intersect="true" visible="false" >
<attribute name="price" />
<attribute name="new_submittleurl" />
</link-entity>
</link-entity>
</entity>
</fetch>

Kingswaysoft Metadata Fields Return Null

Is there a bug in Kingwaysoft where some metadata fields return null? I have a large project downloading all account fields and metadata, and they all work except for owneridtype and a few others. Fields like customertypecodename come over fine, and I've verified that owneridtype is mapped the same as all others. My source is a fetchxml query.
I'm seeing the problem for these account fields, as well as for regardingobjecttypecode on the activitypointer entity:
owneridtype
donotsendmarketingmaterialname
isprivatename
masteraccountidname
owneridtype
Here is my query, minus custom fields. I can add those if needed.
<fetch mapping='logical'>
<entity name='account'>
<attribute name='accountcategorycode'/>
<attribute name='accountcategorycodename'/>
<attribute name='accountclassificationcode'/>
<attribute name='accountclassificationcodename'/>
<attribute name='accountid'/>
<attribute name='accountnumber'/>
<attribute name='accountratingcode'/>
<attribute name='accountratingcodename'/>
<attribute name='address1_addressid'/>
<attribute name='address1_addresstypecode'/>
<attribute name='address1_addresstypecodename'/>
<attribute name='address1_city'/>
<attribute name='address1_composite'/>
<attribute name='address1_country'/>
<attribute name='address1_county'/>
<attribute name='address1_fax'/>
<attribute name='address1_freighttermscode'/>
<attribute name='address1_freighttermscodename'/>
<attribute name='address1_latitude'/>
<attribute name='address1_line1'/>
<attribute name='address1_line2'/>
<attribute name='address1_line3'/>
<attribute name='address1_longitude'/>
<attribute name='address1_name'/>
<attribute name='address1_postalcode'/>
<attribute name='address1_postofficebox'/>
<attribute name='address1_primarycontactname'/>
<attribute name='address1_shippingmethodcode'/>
<attribute name='address1_shippingmethodcodename'/>
<attribute name='address1_stateorprovince'/>
<attribute name='address1_telephone1'/>
<attribute name='address1_telephone2'/>
<attribute name='address1_telephone3'/>
<attribute name='address1_upszone'/>
<attribute name='address1_utcoffset'/>
<attribute name='address2_addressid'/>
<attribute name='address2_addresstypecode'/>
<attribute name='address2_addresstypecodename'/>
<attribute name='address2_city'/>
<attribute name='address2_composite'/>
<attribute name='address2_country'/>
<attribute name='address2_county'/>
<attribute name='address2_fax'/>
<attribute name='address2_freighttermscode'/>
<attribute name='address2_freighttermscodename'/>
<attribute name='address2_latitude'/>
<attribute name='address2_line1'/>
<attribute name='address2_line2'/>
<attribute name='address2_line3'/>
<attribute name='address2_longitude'/>
<attribute name='address2_name'/>
<attribute name='address2_postalcode'/>
<attribute name='address2_postofficebox'/>
<attribute name='address2_primarycontactname'/>
<attribute name='address2_shippingmethodcode'/>
<attribute name='address2_shippingmethodcodename'/>
<attribute name='address2_stateorprovince'/>
<attribute name='address2_telephone1'/>
<attribute name='address2_telephone2'/>
<attribute name='address2_telephone3'/>
<attribute name='address2_upszone'/>
<attribute name='address2_utcoffset'/>
<attribute name='adx_createdbyipaddress'/>
<attribute name='adx_createdbyusername'/>
<attribute name='adx_modifiedbyipaddress'/>
<attribute name='adx_modifiedbyusername'/>
<attribute name='aging30'/>
<attribute name='aging30_base'/>
<attribute name='aging60'/>
<attribute name='aging60_base'/>
<attribute name='aging90'/>
<attribute name='aging90_base'/>
<attribute name='businesstypecode'/>
<attribute name='businesstypecodename'/>
<attribute name='cdi_allowtextmessages'/>
<attribute name='cdi_allowtextmessagesname'/>
<attribute name='CFBcrmconsulting'/>
<attribute name='CFBcrmconsultingname'/>
<attribute name='CFBcrmelementsoutlook'/>
<attribute name='CFBcrmelementsoutlookname'/>
<attribute name='CFBcrmelementsrealestate'/>
<attribute name='CFBcrmelementsrealestatename'/>
<attribute name='CFBcrmlicenses'/>
<attribute name='CFBcrmlicensesname'/>
<attribute name='CFPEmailSoftware'/>
<attribute name='CFPEmailSoftwarename'/>
<attribute name='CFPnumberofemployeesrange'/>
<attribute name='CFPnumberofemployeesrangename'/>
<attribute name='CFProle'/>
<attribute name='CFProlename'/>
<attribute name='CFPSalesForceSoftware'/>
<attribute name='CFPSalesForceSoftwarename'/>
<attribute name='createdby'/>
<attribute name='createdbyexternalparty'/>
<attribute name='createdbyexternalpartyname'/>
<attribute name='createdbyexternalpartyyominame'/>
<attribute name='createdbyname'/>
<attribute name='createdbyyominame'/>
<attribute name='createdon'/>
<attribute name='createdonbehalfby'/>
<attribute name='createdonbehalfbyname'/>
<attribute name='createdonbehalfbyyominame'/>
<attribute name='creditlimit'/>
<attribute name='creditlimit_base'/>
<attribute name='creditonhold'/>
<attribute name='creditonholdname'/>
<attribute name='customersizecode'/>
<attribute name='customersizecodename'/>
<attribute name='customertypecode'/>
<attribute name='customertypecodename'/>
<attribute name='defaultpricelevelid'/>
<attribute name='defaultpricelevelidname'/>
<attribute name='description'/>
<attribute name='donotbulkemail'/>
<attribute name='donotbulkemailname'/>
<attribute name='donotbulkpostalmail'/>
<attribute name='donotbulkpostalmailname'/>
<attribute name='donotemail'/>
<attribute name='donotemailname'/>
<attribute name='donotfax'/>
<attribute name='donotfaxname'/>
<attribute name='donotphone'/>
<attribute name='donotphonename'/>
<attribute name='donotpostalmail'/>
<attribute name='donotpostalmailname'/>
<attribute name='donotsendmarketingmaterialname'/>
<attribute name='donotsendmm'/>
<attribute name='emailaddress1'/>
<attribute name='emailaddress2'/>
<attribute name='emailaddress3'/>
<attribute name='entityimage'/>
<attribute name='entityimage_timestamp'/>
<attribute name='entityimage_url'/>
<attribute name='entityimageid'/>
<attribute name='exchangerate'/>
<attribute name='fax'/>
<attribute name='ftpsiteurl'/>
<attribute name='hoovers_companyid'/>
<attribute name='hoovers_hooversupdatescheduled'/>
<attribute name='hoovers_hooversupdatescheduledname'/>
<attribute name='hoovers_linkedtohoovers'/>
<attribute name='hoovers_linkedtohooversname'/>
<attribute name='importsequencenumber'/>
<attribute name='industrycode'/>
<attribute name='industrycodename'/>
<attribute name='isprivatename'/>
<attribute name='lastonholdtime'/>
<attribute name='lastusedincampaign'/>
<attribute name='marketcap'/>
<attribute name='marketcap_base'/>
<attribute name='masteraccountidname'/>
<attribute name='masteraccountidyominame'/>
<attribute name='masterid'/>
<attribute name='merged'/>
<attribute name='mergedname'/>
<attribute name='modifiedby'/>
<attribute name='modifiedbyexternalparty'/>
<attribute name='modifiedbyexternalpartyname'/>
<attribute name='modifiedbyexternalpartyyominame'/>
<attribute name='modifiedbyname'/>
<attribute name='modifiedbyyominame'/>
<attribute name='modifiedon'/>
<attribute name='modifiedonbehalfby'/>
<attribute name='modifiedonbehalfbyname'/>
<attribute name='modifiedonbehalfbyyominame'/>
<attribute name='msa_managingpartnerid'/>
<attribute name='msa_managingpartneridname'/>
<attribute name='msa_managingpartneridyominame'/>
<attribute name='name'/>
<attribute name='numberofemployees'/>
<attribute name='onholdtime'/>
<attribute name='opendeals'/>
<attribute name='opendeals_date'/>
<attribute name='opendeals_state'/>
<attribute name='openrevenue'/>
<attribute name='openrevenue_base'/>
<attribute name='openrevenue_date'/>
<attribute name='openrevenue_state'/>
<attribute name='originatingleadid'/>
<attribute name='originatingleadidname'/>
<attribute name='originatingleadidyominame'/>
<attribute name='overriddencreatedon'/>
<attribute name='ownerid'/>
<attribute name='owneridname'/>
<attribute name='owneridtype'/>
<attribute name='owneridyominame'/>
<attribute name='ownershipcode'/>
<attribute name='ownershipcodename'/>
<attribute name='owningbusinessunit'/>
<attribute name='owningteam'/>
<attribute name='owninguser'/>
<attribute name='parentaccountid'/>
<attribute name='parentaccountidname'/>
<attribute name='parentaccountidyominame'/>
<attribute name='participatesinworkflow'/>
<attribute name='participatesinworkflowname'/>
<attribute name='paymenttermscode'/>
<attribute name='paymenttermscodename'/>
<attribute name='preferredappointmentdaycode'/>
<attribute name='preferredappointmentdaycodename'/>
<attribute name='preferredappointmenttimecode'/>
<attribute name='preferredappointmenttimecodename'/>
<attribute name='preferredcontactmethodcode'/>
<attribute name='preferredcontactmethodcodename'/>
<attribute name='preferredequipmentid'/>
<attribute name='preferredequipmentidname'/>
<attribute name='preferredserviceid'/>
<attribute name='preferredserviceidname'/>
<attribute name='preferredsystemuserid'/>
<attribute name='preferredsystemuseridname'/>
<attribute name='preferredsystemuseridyominame'/>
<attribute name='primarycontactid'/>
<attribute name='primarycontactidname'/>
<attribute name='primarycontactidyominame'/>
<attribute name='primarysatoriid'/>
<attribute name='primarytwitterid'/>
<attribute name='processid'/>
<attribute name='revenue'/>
<attribute name='revenue_base'/>
<attribute name='sharesoutstanding'/>
<attribute name='shippingmethodcode'/>
<attribute name='shippingmethodcodename'/>
<attribute name='sic'/>
<attribute name='slaid'/>
<attribute name='slainvokedid'/>
<attribute name='slainvokedidname'/>
<attribute name='slaname'/>
<attribute name='stageid'/>
<attribute name='statecode'/>
<attribute name='statecodename'/>
<attribute name='statuscode'/>
<attribute name='statuscodename'/>
<attribute name='stockexchange'/>
<attribute name='telephone1'/>
<attribute name='telephone2'/>
<attribute name='telephone3'/>
<attribute name='territorycode'/>
<attribute name='territorycodename'/>
<attribute name='territoryid'/>
<attribute name='territoryidname'/>
<attribute name='tickersymbol'/>
<attribute name='timezoneruleversionnumber'/>
<attribute name='transactioncurrencyid'/>
<attribute name='transactioncurrencyidname'/>
<attribute name='traversedpath'/>
<attribute name='utcconversiontimezonecode'/>
<attribute name='versionnumber'/>
<attribute name='websiteurl'/>
<attribute name='yominame'/>
<filter>
<condition attribute='modifiedon' operator='gt' value='#[User::LastRunDate]' />
</filter>
</entity>
</fetch>
Can you please try to include the ownerid field in your query and check to see if you can get value for the owneridtype field?
Note that in order to read from those virtual fields (such as lookup name or OptionSet name fields), you must include their supporting/dependent fields (the lookup fields or OptionSet fields).
If you have any other questions, please feel free to let us know.
I faced the same problem. I was able to get the codeName and lookUp through Entity as a data source. This does not work directly with fetchXml.

using Nlog and writing to file as json

I think I'm missing something as I can't seem to figure out how to have it write to a log file in json format using NLog setup in configuration file. The straight rolling file works fine, but not the json. The json target only outputs the message (not in json).
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets async="true">
<target xsi:type="File" name="rollingFile" fileName="${basedir}/logs/${shortdate}.log" archiveFileName="${basedir}/logs/{shortdate}_Archive{###}.log" archiveAboveSize="1000000" archiveNumbering="Sequence" layout="${longdate} ${uppercase:${level}} ${callsite} ${message}" />
<target xsi:type="File"
name="rollingFileJson"
fileName="${basedir}/logs/${shortdate}.json"
archiveFileName="${basedir}/logs/{shortdate}_Archive{###}.json"
archiveAboveSize="1000000"
archiveNumbering="Sequence"
layout="${json-encode} ${message}">
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="rollingFile" />
<logger name="*" minlevel="Trace" writeTo="rollingFileJson" />
</rules>
</nlog>
As of the release of NLog 4.0.0 it is possible to use a layout that renders events as structured JSON documents.
Example taken from NLog project site:
<target name="jsonFile" xsi:type="File" fileName="${logFileNamePrefix}.json">
<layout xsi:type="JsonLayout">
<attribute name="time" layout="${longdate}" />
<attribute name="level" layout="${level:upperCase=true}"/>
<attribute name="message" layout="${message}" />
</layout>
</target>
Edit:
You can also create it in code.
Here is the link to the specific part of documentation.
And here the copied example:
var jsonLayout = new JsonLayout
{
Attributes =
{
new JsonAttribute("type", "${exception:format=Type}"),
new JsonAttribute("message", "${exception:format=Message}"),
new JsonAttribute("innerException", new JsonLayout
{
Attributes =
{
new JsonAttribute("type", "${exception:format=:innerFormat=Type:MaxInnerExceptionLevel=1:InnerExceptionSeparator=}"),
new JsonAttribute("message", "${exception:format=:innerFormat=Message:MaxInnerExceptionLevel=1:InnerExceptionSeparator=}"),
}
},
//don't escape layout
false)
}
};
For more info read the docs.
As per NLog documentation: json-encode will only escape output of another layout using JSON rules. It will not "convert" the output to JSON. You'll have to do that yourself.
'{ "date":"${longdate}","level":"${level}","message":${message}}'
Take a look at this question for more details.

Date Parameters in FetchXML

I am using FetchXML in SSRS 2008 to create a report from CRM 2011. I want to have parameters in the report so you can show the records between From Date - To Date. This is the Query I have so far.
<fetch>
<entity name="appointment">
<attribute name="scheduledstart" />
<link-entity name="systemuser" from="systemuserid" to="ownerid">
<attribute name="firstname" alias="ownerFirstName" />
<attribute name="lastname" alias="ownerLastName" />
</link-entity>
<link-entity name="contact" from="contactid" to="new_contactperson">
<attribute name="parentcustomerid" alias="parentaccount" />
<attribute name="new_businessunit" alias="businessunit" />
</link-entity>
<attribute name="new_contactperson" />
<attribute name="subject" />
<attribute name="new_coldernotes" />
<link-entity name="activityparty" from="activityid" to="activityid">
<attribute name="participationtypemask" alias="participationtypemask" />
<filter>
<condition attribute="participationtypemask" operator="eq" value="9" />
</filter>
<link-entity name="systemuser" from="systemuserid" to="partyid">
<attribute name="fullname" />
</link-entity>
</link-entity>
<order attribute="scheduledstart" descending="true" />
</entity>
</fetch>
How would I make it so I can filter between the dates?
Thanks!
Not sure if you have access to the native CRM client, but the Advanced Find view quickly generates this sample FetchXML:
<filter type="and">
<condition attribute="modifiedon" operator="on-or-after" value="2011-10-04" />
<condition attribute="modifiedon" operator="on-or-before" value="2011-11-13" />
</filter>