Sending Custom Dimension in Event to Google Analytics - node.js

Hello I am trying to attach custom dimension while sending events to Google Analytics using NodeJS.
I am using universal analytics npm package.
When I am sending only one custom dimension it is working fine,
but the problem is while setting more than one custom dimensions only the first custom dimension is getting tracked.
visitor.set("cd1", <value>);
visitor.set("cd2", <value>);
visitor.event(params).send();
Only value of cd1 is reflecting.
Any solution?

Finally found the required format.
We need to send in this format:
params = {
ec: eventCategoryValue,
ea: eventActionValue,
el: eventLabelValue,
cd1: valueOfCustomDimensionAtIndex1,
cd2: valueOfCustomDimensionAtIndex2
}
It will reflect in GA.

Related

Incorrect component name in App Insights on Azure, using OpenTelemetry

I'm using OpenTelemetry to trace my service running on Azure.
Azure Application Map is showing incorrect name for the components sending the trace. It is also sending incorrect Cloud RoleName which is probably why this is happening. The Cloud RoleName that App Insights is displaying is Function App name and not the Function name.
In my Azure Function (called FirewallCreate), I start a trace using following util method:
def get_otel_new_tracer(name=__name__):
# Setup a TracerProvider(). For more details read:
# https://learn.microsoft.com/en-us/azure/azure-monitor/app/opentelemetry-enable?tabs=python#set-the-cloud-role-name-and-the-cloud-role-instance
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create(
{
SERVICE_NAME: name,
SERVICE_NAMESPACE: name,
# SERVICE_INSTANCE-ID: "my-instance-id"
}
)
)
)
# Send messages to Exporter in batches
span_processor = BatchSpanProcessor(
AzureMonitorTraceExporter.from_connection_string(
os.environ["TRACE_APPINSIGHTS_CONNECTION_STRING"]
)
)
trace.get_tracer_provider().add_span_processor(span_processor)
return trace.get_tracer(name)
def firewall_create():
tracer = get_otel_new_tracer("FirewallCreate")
with tracer.start_new_span("span-firewall-create") as span:
# do some stuff
...
The traces show another function name, in the same function app (picture attached).
What mistake I could be making?
The component has 0 ms and 0 calls in it. What does it mean? How to interpret it?
Hey thanks for trying out OpenTelemetry with Application Insights! First of all, are you using the azure-monitor-opentelemetry-exporter, and if so, what version are you using? I've also answered your questions inline:
What mistake I could be making?
What name are you trying to set your component to? The exporter will attempt to set your cloudRoleName to <service_namespace>.<service_name> by default that you set in your Resource. If <service_namespace> is not populated, it takes the value of <service_name>.
The component has 0 ms and 0 calls in it. What does it mean? How to interpret it?
Is this the only node in your application map? We need to first find whether this node is created by the exporter or by the functions runtime itself.

Azure Functions Orchestration using Logic App

I have multiple Azure Functions which carry out small tasks. I would like to orchestrate those tasks together using Logic Apps, as you can see here:
Logic App Flow
I am taking the output of Function 1 and inputting parts of it into Function 2. As I was creating the logic app, I realized I have to parse the response of Function 1 as JSON in order to access the specific parameters I need. Parse JSON requires me to provide an example schema however, I need to be able to parse the response as JSON without this manual step.
One solution I thought would work was to register Function 1 with APIM and provide a response schema. This doesn't seem to be any different to calling the Function directly.
Does anyone have any suggestions for how to get the response of a Function as a JSON/XML?
You can run Javascript snippets and dynamic parse the response from Function 1 without providing a sample.
e.g.
var data = Object.keys(workflowContext.trigger.outputs.body.Body);
var key = data.filter(s => s.includes('Property')).toString(); // to get element - Property - dynamic content
return workflowContext.trigger.outputs.body.Body[key];
https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-add-run-inline-code?tabs=consumption

Output MQTT data into a Node-Red graph

I am currently using an MQTT client that is linked with some Arduino code that produces numerical outputs at a 2 second interval. This is further linked to a NodeRed flow where it reads the input passed through the broker, and outputs it as a payload message on the dashboard. I am wanting to produce a graph node that is connected to the MQTT subscriber and shows real time data in the UI. I attempted this in the way shown in the example image as I wanted to still see the information in the dashboard, but I could not get a proper graph to appear. Could anyone help me with how I could do this?
To get the chart node to work properly you need to feed it just the numerical value.
Your MQTT messages are actually a string as follows Temperature = -70.06660 degrees so you will need to extract the number from the string.
The quickest way to do this is probably to insert a function node between the MQTT-in node and the chart node.
In the function node add the following code:
var parts = msg.payload.split(" ");
msg.payload = parseFloat(parts[2]);
return msg;
This should now just feed the numerical part to the chart node.

How can I clear an external ID on a record in NetSuite?

I need to clear/reset the external ID on a record in NetSuite, but nothing I do is working.
Some of the InventoryItem records are incorrectly mapped to records in another system. I have an application that can sync up the two systems, but I need to clear NetSuite's external IDs first.
Responses don't really need to be SOAP-specific. If you know how to do it with some specific NetSuite/SuiteTalk client, that might point me in the right direction.
What I've Tried
First up, I tried using the nullFieldList... but maybe it doesn't work because externalId is an attribute, not an element?
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<core:nullFieldList xsi:type="core:NullField">
<core:name>externalId</core:name>
</core:nullFieldList>
</messages:record>
</messages:update>
The external ID is just a string, so I tried just setting it to blank. Didn't work either.
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<accounting:externalId></accounting:externalId>
</messages:record>
</messages:update>
I even tried setting the external ID to 0, but I get back a "not unique identifier" error
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<accounting:externalId>0</accounting:externalId>
</messages:record>
</messages:update>
Other Info
I'm using NetSuite's SOAP API v.2013_1
When I say "it doesn't work", I mean: after I do the update, I get a success response similar to the following:
<readResponse>
<platformCore:status isSuccess="true" xmlns:platformCore="urn:core_2013_1.platform.webservices.netsuite.com"/>
<record internalId="7777" externalId="42" xsi:type="listAcct:InventoryItem" xmlns:listAcct="urn:accounting_2013_1.lists.webservices.netsuite.com">
<!-- snip -->
</record>
</readResponse>
If you are using scripts in netsuite you can run a scheduled script to clear records in NS by loading each record and setting the externalid to '' using the following simple code:
var rec= nlapiLoadRecord(type,id);
rec.setFieldValue('externalid','');
nlapiSubmitRecord(rec);
This seemed to work for me in my enviornment which was on 2015.2.
Unfortunately my understanding is that once you set an externalid you cannot clear it, you can set it to another value, but not back to null. I have experienced this both using SuiteScript as well as a Boomi process that uses the 2014.1 endpoint. This may have changed in the recent releases, as I have not tried it recently with SuiteScript nor with a newer endpoint.
You can eliminate the externalId on a record once it's been set. Here's an example using the NetSuite gem:
ns_customer = NetSuite::Records::Customer.get external_id: 'ext_id'
ns_customer.external_id = ''
ns_customer.update
Here's the corresponding XML for update:
<env:Body>
<platformMsgs:update>
<platformMsgs:record xsi:type="listRel:Customer" platformMsgs:internalId="199113" platformMsgs:externalId=""/>
</platformMsgs:update>
</env:Body>
I have had to attempt this before as well. I know the pains you describe. I ended up putting a "-" in front of my external ID to unlink it between my systems. You can do this in SOAP or even as a simple one time csv upload. As it was one time, I did csv.

Incremental loading in Azure Mobile Services

Given the following code:
listView.ItemsSource =
App.azureClient.GetTable<SomeTable>().ToIncrementalLoadingCollection();
We get incremental loading without further changes.
But what if we modify the read.js server side script to e.g. use mssql to query another table instead. What happens to the incremental loading? I'm assuming it breaks; if so, what's needed to support it again?
And what if the query used the untyped version instead, e.g.
App.azureClient.GetTable("SomeTable").ReadAsync(...)
Could incremental loading be somehow supported in this case, or must it be done "by hand" somehow?
Bonus points for insights on how Azure Mobile Services implements incremental loading between the server and the client.
The incremental loading collection works by sending the $top and $skip query parameters (those are also sent when you do a query by using the .Take and .Skip methods in the table). So if you want to modify the read script to do something other than the default behavior, while still maintaining the ability to use that table with an incremental loading collection, you need to take those values into account.
To do that, you can ask for the query components, which will contain the values, as shown below:
function read(query, user, request) {
var queryComponents = query.getComponents();
console.log('query components: ', queryComponents); // useful to see all information
var top = queryComponents.take;
var skip = queryComponents.skip;
// do whatever you want with those values, then call request.respond(...)
}
The way it's implemented at the client is by using a class which implements the ISupportIncrementalLoading interface. You can see it (and the full source code for the client SDKs) in the GitHub repository, or more specifically the MobileServiceIncrementalLoadingCollection class (the method is added as an extension in the MobileServiceIncrementalLoadingCollectionExtensions class).
And the untyped table does not have that method - as you can see in the extension class, it's only added to the typed version of the table.

Resources