Configuring NewRelic with MassTransit (Similar to NServiceBus) - c#

I've been trying to setup the custom metrics inside NewRelic for MassTransit similar to how NServiceBus works with NewRelic. It seems that this is pretty easy to achieve using the NewRelic .Net Custom Transactions documentation.
So far from checking out the MassTransit code on GitHub I've manage to put together a simple instrumentation file for MassTransit but this only contains Message Sends, but I really want message received as well but i cant seem to find the first interception which is not tied to a transport implementation.
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory metricName="MassTransit/Send">
<match assemblyName="MassTransit" className="MassTransit.Transports.SendEndpoint">
<exactMethodMatcher methodName="Send" parameters="!!0,System.Threading.CancellationToken" />
<exactMethodMatcher methodName="Send" parameters="!!0,MassTransit.Pipeline.IPipe`1[MassTransit.SendContext`1[!!0]],System.Threading.CancellationToken" />
</match>
</tracerFactory>
</instrumentation>
</extension>
The example of the NServiceBus instrumentation file that I'm trying to create the equivalent MassTransit one is below:
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory>
<match assemblyName="NServiceBus.Core" className="NServiceBus.InvokeHandlersBehavior">
<exactMethodMatcher methodName="Invoke" parameters="NServiceBus.Pipeline.Contexts.IncomingContext,System.Action" />
</match>
</tracerFactory>
<tracerFactory>
<match assemblyName="NServiceBus.Core" className="NServiceBus.Unicast.UnicastBus">
<exactMethodMatcher methodName="SendMessage" parameters="NServiceBus.Unicast.SendOptions,NServiceBus.Unicast.Messages.LogicalMessage" />
</match>
</tracerFactory>
</instrumentation>
</extension>
UPDATE
As suggested by Chris Patterson I've updated to the new package so there is a method I can hook on to within the ReceivePipe.
I've tried to then instrument this method but with no success, i can how ever see the that its possible to instrument within the logs when turning on the ALL logging:
[Trace] 2015-10-19 09:08:45 Possibly instrumenting: (Module: D:\Liberis\Services\Liberis.Salesforce.Service\MassTransit.dll, AppDomain: Liberis.Salesforce.Service.exe)[MassTransit]MassTransit.Pipeline.Pipes.ReceivePipe.MassTransit.Pipeline.IPipe<MassTransit.ReceiveContext>.Send(MassTransit.ReceiveContext)
I've also tried updating the the configuration to the following to match the above but still had no success:
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="MassTransit/Receive">
<match assemblyName="MassTransit" className="MassTransit.Pipeline.Pipes.ReceivePipe.MassTransit.Pipeline.IPipe<MassTransit.ReceiveContext>">
<exactMethodMatcher methodName="Send" parameters="MassTransit.ReceiveContext" />
</match>
</tracerFactory>
</instrumentation>
</extension>
I've also tried to use the nrconfig tool but that only outputs the following for the ReceivePipe class:
<match assemblyName="MassTransit" className="MassTransit.Pipeline.Pipes.ReceivePipe">
<exactMethodMatcher methodName=".ctor" parameters="MassTransit.Pipeline.IPipe`1<MassTransit.ReceiveContext>,MassTransit.Pipeline.IConsumePipe" />
</match>
I have a feeling that I need to instrument it differently due to the class implicitly implementing the IPipe<ReceiveContext> interface?

You should be able to hook the ReceivePipe.Send method in a similar fashion.
https://github.com/MassTransit/MassTransit/blob/master/src/MassTransit/Pipeline/Pipes/ReceivePipe.cs#L30
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory metricName="MassTransit/Receive">
<match assemblyName="MassTransit" className="MassTransit.Pipeline.Pipe.ReceivePipe">
<exactMethodMatcher methodName="Send" parameters="ReceiveContext" />
</match>
</tracerFactory>
</instrumentation>
</extension>
At least, that's my guess on the XML syntax, but the method is sound.

With some help from #Chris Patterson I've managed to figure it out, lot more effort than I thought it should of been.
Below is the configuration xml that is required:
<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
<instrumentation>
<tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="MassTransit/Send">
<match assemblyName="MassTransit" className="MassTransit.Transports.SendEndpoint">
<exactMethodMatcher methodName="Send" parameters="!!0,System.Threading.CancellationToken" />
<exactMethodMatcher methodName="Send" parameters="!!0,MassTransit.Pipeline.IPipe`1[MassTransit.SendContext`1[!!0]],System.Threading.CancellationToken" />
</match>
</tracerFactory>
<tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="MassTransit/Receive">
<match assemblyName="MassTransit" className="MassTransit.Pipeline.Pipes.ReceivePipe">
<exactMethodMatcher methodName="MassTransit.Pipeline.IPipe<MassTransit.ReceiveContext>.Send" parameters="MassTransit.ReceiveContext" />
</match>
</tracerFactory>
</instrumentation>
</extension>
Seems like the method signature totally changes due to implicitly implementing the IPipe interface.
I've also added this to a github repository - https://github.com/LiberisLabs/NewRelic.Agent.CustomTransactions

Related

C# Web Reference - ArrayOfString not serialising

I am using Web References in C# to interface with Magento, which uses a SOAP API. The WSDL contains lots of definitions as you can imagine, but I'm having a problem with this particular one:
<complexType name="ArrayOfString">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>
Any propertes of a method that are an ArrayOfString are being brought back to my code as string[], which is fine, but when serialising it back to Magento it's serialising it as below
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:Magento" xmlns:types="urn:Magento/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:catalogProductCreate>
<sessionId xsi:type="xsd:string">xxxxxxxxxxxxxxxxxxxxxxx</sessionId>
<type xsi:type="xsd:string">simple</type>
<set xsi:type="xsd:string">63</set>
<sku xsi:type="xsd:string">CHRISTEST</sku>
<productData href="#id1" />
</tns:catalogProductCreate>
<tns:catalogProductCreateEntity id="id1" xsi:type="tns:catalogProductCreateEntity">
<categories href="#id2" />
<websites href="#id3" />
<name xsi:type="xsd:string">Chris Test 8</name>
<description xsi:type="xsd:string">fsd</description>
<short_description xsi:type="xsd:string">Chris Test 8</short_description>
<weight xsi:type="xsd:string">0.0000</weight>
<status xsi:type="xsd:string">1</status>
<visibility xsi:type="xsd:string">1</visibility>
<category_ids href="#id4" />
<website_ids href="#id5" />
<price xsi:type="xsd:string">0.00000</price>
<tax_class_id xsi:type="xsd:string">4</tax_class_id>
<tier_price href="#id6" />
</tns:catalogProductCreateEntity>
<soapenc:Array id="id2" soapenc:arrayType="xsd:string[0]" />
<soapenc:Array id="id3" soapenc:arrayType="xsd:string[0]" />
<soapenc:Array id="id4" soapenc:arrayType="xsd:string[1]">
<Item>35</Item>
</soapenc:Array>
<soapenc:Array id="id5" soapenc:arrayType="xsd:string[1]">
<Item>1</Item>
</soapenc:Array>
<soapenc:Array id="id6" soapenc:arrayType="tns:catalogProductTierPriceEntity[0]" />
</soap:Body>
</soap:Envelope>
And this is resulting in the arrays being ignored. I believe the reason the ArrayOfString entity isn't being added to my service model is because it has a 'restriction', but I'm going to need this to get the data back to Magento. Any ideas guys?

Facebook OAuth Redirects and Custom App URL Scehem

I'm trying to get Facebook to redirect back to my Unity application (running on android) after a call to https://facebook.com/v2.8/dialog/oauth. I've created a custom URL scheme in my android app like myApp://. However, when I attempt to send the OAuth request through to facebook, it tells me that the redirect_uri is not supported. I've tried to add my custom URL to my Facebook app's OAuth settings, but it says it is not a valid URL (which makes sense, as it's technically not).
The request:
var url = string.Format("https://facebook.com/v2.8/dialog/oauth?client_id={0}&response_type=token&redirect_uri={1}", "MYAPPID", "redfish%3A%2F%2Ffacebooklogin");
My app's AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:icon="#drawable/app_icon" android:label="#string/app_name">
<activity android:name=".MainActivity" android:label="#string/app_name" android:launchMode="singleTask" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="sensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="redfish" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
</application>
</manifest>
Code for catching the redirect in unity:
public class OnAcessToken : MonoBehaviour {
void OnAccessToken(string accessToken)
{
Debug.Log("Received access token: " + accessToken);
SceneManager.LoadScene("FileSelect");
}
}
The class OnAccessToken is hit using a custom library generated by the instructions at http://oferei.com/2013/06/serverless-instagram-authentication/.
What I'm asking is how to I get Facebook to allow my custom URL scheme as a valid redirect_uri? Or am I going about this the wrong way.
Ended up answering my own question with some additional research. Using a custom URL schema for android isn't necessary, and according to Google, the practice of using something like myApp:// is being deprecated.
Instead, my schema is now http://myApp.auth, and the corresponding intent filter looks like this:
<intent-filter>
<data android:scheme="http"
android:host="redfish.auth/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
Now, in Facebook's settings, I can set http://redfish.auth as an acceptable OAuth URL, and it won't complain since it has the http schema. This overrides the host rather than the schema, so it works in Chromium browsers (previously did not because of the aforementioned Chrome standards).
So, when I make a call to http://redfish.auth/facebooklogin, it redirects back to my app!
References: https://developer.android.com/guide/components/intents-filters.html

Update lucene search index in sitecore

I have defined lucene search index in sitecore 7.2 initial release. it's working fine but it did not updates itself on publish. although i have defined index updated both "OnPublishEndAsynchronousStrategy" & "RebuildAfterFullPublishStrategy" strategy as below.
<strategies hint="list:AddStrategy">
<strategy ref="contentSearch/indexUpdateStrategies/onPublishEndAsync" />
</strategies>
but it did not updates on publish a single item in smart publish.
I also have an alternative to rebuild index on publish from code
Sitecore.ContentSearch.ContentSearchManager.GetIndex("SearchIndexName").Rebuild();
but it's seems not a proper / efficient way to this.
Configuration code for reference:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<contentSearch>
<configuration type="Sitecore.ContentSearch.ContentSearchConfiguration, Sitecore.ContentSearch">
<indexes hint="list:AddIndex">
<index id="my_sitesearch_index" type="Sitecore.ContentSearch.LuceneProvider.LuceneIndex, Sitecore.ContentSearch.LuceneProvider">
<param desc="name">$(id)</param>
<param desc="folder">$(id)</param>
<param desc="propertyStore" ref="contentSearch/databasePropertyStore" param1="$(id)" />
<configuration ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration">
<indexAllFields>true</indexAllFields>
<include hint="list:IncludeTemplate">
<cmb>{FBAC6C1C-0B59-401A-B01A-8B7435EFA6A6}</cmb>
<home>{4291EDE0-8A5E-4B2E-A08F-D1299B262181}</home>
<category>{0D2CB285-CD2F-4813-A8F8-59E18507CD60}</category>
<externalLink>{77AD69A5-9F82-4955-B678-140EE6C8D5D8}</externalLink>
<fullwidthmap>{EFC1AD32-1495-46D8-B7BD-875B40D23CDE}</fullwidthmap>
<newsdetail>{BE9BD444-A1B7-43F0-98B1-61AF9A4CD83C}</newsdetail>
<product>{45E6DFFD-481E-40D4-923B-D5FD903EE44B}</product>
<productListing>{16E3C0EC-A5D7-49F3-B18E-AA0434DEAD3F}</productListing>
<segment>{99F070CF-7D8C-4F76-91B1-5B165DB7D7B4}</segment>
</include>
<fieldMap ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration/fieldMap">
<fieldNames hint="raw:AddFieldByFieldName">
<field fieldName="predictive_search_keywords" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider">
<analyzer type="Sitecore.ContentSearch.LuceneProvider.Analyzers.LowerCaseKeywordAnalyzer, Sitecore.ContentSearch.LuceneProvider" />
</field>
</fieldNames>
</fieldMap>
<include hint="list:IncludeField">
</include>
</configuration>
<strategies hint="list:AddStrategy">
<strategy ref="contentSearch/indexUpdateStrategies/onPublishEndAsync" />
</strategies>
<commitPolicyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch">
<policies hint="list:AddCommitPolicy">
<policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
</policies>
</commitPolicyExecutor>
<locations hint="list:AddCrawler">
<crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
<Database>web</Database>
<Root>/sitecore/content</Root>
</crawler>
</locations>
</index>
</indexes>
</configuration>
</contentSearch>
</sitecore>
</configuration>
Thanks,

Product LaunchCondition in WiX if no RegistryValue or RegistryValue is below 1.3.44

(I need to get this to work for the Product / .msi directly, not by using Bundle / Burn.)
(I am using WiX 3.6.)
Fragment that puts a registry value into a variable
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include $(sys.CURRENTDIR)Deployment\Data\Statics.wxi ?>
<Fragment>
<util:RegistrySearch Root="HKCU" Key="$(var.Line.Reg.Path)" Value="Version" Variable="AppAlreadyInstalled" />
</Fragment>
</Wix>
Main product with non-working condition
<Product Name="$(var.App.Title)" Manufacturer="!(loc.Company)" Language="!(loc.Lang)" Id="*" Version="$(var.VersionNumber)" UpgradeCode="$(var.App.UpgradeCode)">
<Package Id="*" InstallerVersion="300" Compressed="yes" InstallScope="$(var.App.Elevation)" InstallPrivileges="limited" />
<DirectoryRef Id="TARGETDIR" />
<MajorUpgrade Schedule="afterInstallValidate" DowngradeErrorMessage="!(loc.Msi.NewerVersionInstalled)" />
<Property Id='DiskPrompt' Value="$(var.App.Title) Installation Media" />
<Media Id="1" Cabinet="Media.cab" EmbedCab="yes" DiskPrompt="#1" />
<Icon Id="AppIcon" SourceFile="$(var.Icon.Path)" />
<Condition Message="Newer version already installed.">
<![CDATA[Installed OR AppAlreadyInstalled]]>
</Condition>
<Feature Id="ProductFeature" Level="1">
...
</Feature>
</Product>
I believe AppAlreadyInstalled is never set at the moment because it is in a fragment in a different file.
Then I actually want the installation to proceed if the registry value is NOT found at all / does not exist.
But if it does it exist, I would like the installation to proceed only if the registry value is below a certain value e.g. proceed with installation only if AppAlreadyInstalled < 1.3.44; this sounds hard to achieve because the registry value is stored as a string with two full-stops / periods.
Note the registry check is not of the application to-be-installed, which is already taken care of by DowngradeErrorMessage.
WixUtilExtension:RegistrySearch is only for bundles. You need a plain RegistrySearch in the WiX namespace. You can use RegistrySearchRef to pull in a RegistrySearch from a separate fragment.
However, you're right that a version comparison is problematic: MSI does ordinal string comparisons so 1.2 > 1.10. If the install directory is in the registry, you might be better off using a RegistrySearch combined with a DirectorySearch and a FileSearch. FileSearch can search by version using the MinVersion attribute so if there's a file with a version you can use to detect the product, it'll be more reliable than string comparisons.

How to get the list of scheduled tasks using c#?

I need to get the list of scheduled tasks that are present in the local computer.
How can I achieve that using c# for Windows XP?
1 alternative...:
1) you can read from the folder where task are saved ( Ive just tested it - win7)
c:\Windows\System32\Tasks\
this is simple xml file like this :
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2012-04-05T13:28:54.2106589</Date>
<Author>DAVIDDOM\RoyiN</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2012-04-05T13:28:43.2046589</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<RunLevel>LeastPrivilege</RunLevel>
<UserId>DAVIDDOM\RoyiN</UserId>
<LogonType>InteractiveToken</LogonType>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Windows\system32\charmap.exe</Command>
</Exec>
</Actions>
</Task>

Categories

Resources