Introduction
Integrations are only as good as their visibility.
Once data starts flowing between NetSuite and external systems (Shopify, Salesforce, HubSpot, etc.), you need a central dashboard to track whatβs happening β successes, failures, and processing times.
In this guide, weβll build:
- A custom Integration Log record
- A SuiteScript logger utility
- A Suitelet dashboard to display integration metrics and trends
π§± 1. Create a Custom Record for Integration Logs
Custom Record: customrecord_integration_log
Field ID | Label | Type |
---|---|---|
custrecord_source_system | Source System | List/Text |
custrecord_integration_type | Integration Type | Text |
custrecord_status | Status (Success/Failed) | List |
custrecord_message | Log Message | Long Text |
custrecord_reference_id | Reference Record ID | Text |
custrecord_duration | Duration (ms) | Integer |
custrecord_log_date | Log Date | Date/Time |
β Purpose: Acts as the database for all integration events logged via scripts.
βοΈ 2. Logger Utility Script
Create a reusable module (integration_logger.js
):
/**
* @NApiVersion 2.1
* @NModuleScope Public
*/
define(['N/record', 'N/runtime'], (record, runtime) => {
const logEntry = (data) => {
try {
const rec = record.create({ type: 'customrecord_integration_log' });
rec.setValue('custrecord_source_system', data.source || 'Unknown');
rec.setValue('custrecord_integration_type', data.type);
rec.setValue('custrecord_status', data.status);
rec.setValue('custrecord_message', data.message);
rec.setValue('custrecord_reference_id', data.refId);
rec.setValue('custrecord_duration', data.duration || 0);
rec.save();
} catch (e) {
log.error('Integration Log Failed', e);
}
};
return { logEntry };
});
Use this utility inside your RESTlet, Map/Reduce, or User Event scripts to record every integration event.
π 3. Create Saved Searches for Quick Insights
- Daily Success vs Failure
- Filter:
custrecord_log_date
is today - Summary: Count by
custrecord_status
- Filter:
- Top 5 Longest Processes
- Sort by
custrecord_duration
descending - Show integration type and message
- Sort by
- Failures by System
- Filter
custrecord_status = Failed
- Group by
custrecord_source_system
- Filter
β These searches will power the dashboard widgets.
π₯οΈ 4. Build the Suitelet Dashboard
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/ui/serverWidget','N/search'], (ui, search) => {
const onRequest = (ctx) => {
const form = ui.createForm({ title: 'Integration Dashboard' });
const summary = form.addFieldGroup({ id:'summarygrp', label:'Summary Stats' });
const success = getCount('Success');
const failed = getCount('Failed');
form.addField({id:'custpage_success', type:ui.FieldType.INLINEHTML, label:'Success'})
.defaultValue = `<h3 style="color:green">${success}</h3>`;
form.addField({id:'custpage_failed', type:ui.FieldType.INLINEHTML, label:'Failed'})
.defaultValue = `<h3 style="color:red">${failed}</h3>`;
form.addSubtab({id:'details', label:'Recent Logs'});
const sublist = form.addSublist({id:'custpage_loglist', label:'Integration Logs', tab:'details', type:ui.SublistType.LIST});
sublist.addField({id:'source', label:'Source', type:ui.FieldType.TEXT});
sublist.addField({id:'status', label:'Status', type:ui.FieldType.TEXT});
sublist.addField({id:'msg', label:'Message', type:ui.FieldType.TEXT});
getRecentLogs().forEach((log, i) => {
sublist.setSublistValue({id:'source', line:i, value:log.source});
sublist.setSublistValue({id:'status', line:i, value:log.status});
sublist.setSublistValue({id:'msg', line:i, value:log.msg});
});
ctx.response.writePage(form);
};
const getCount = (status) => {
const s = search.create({
type:'customrecord_integration_log',
filters:[['custrecord_status','is',status]],
columns:['internalid']
});
return s.runPaged().count;
};
const getRecentLogs = () => {
const results = [];
const s = search.create({
type:'customrecord_integration_log',
columns:['custrecord_source_system','custrecord_status','custrecord_message'],
sort:[{ name:'created', sort:search.Sort.DESC }]
}).run().getRange({start:0,end:10});
s.forEach(r => results.push({
source:r.getValue('custrecord_source_system'),
status:r.getValue('custrecord_status'),
msg:r.getValue('custrecord_message')
}));
return results;
};
return { onRequest };
});
β Displays success/failure counters and a table of recent logs directly inside NetSuite.
π 5. Optional β Add Charts & Filters
- Integrate with N/ui/serverWidget and inject HTML/JS charts using Chart.js.
- Add date range filters (
from
,to
) for log period analysis. - Include βExport to CSVβ button for auditors.
π 6. Security & Access Control
- Limit dashboard access to Admin & Integration Roles.
- Hide sensitive messages from standard users.
- Implement date filters to avoid loading thousands of logs.
β 7. Best Practices
Tip | Benefit |
---|---|
Use a single logger utility | Centralized error tracking |
Limit dashboard results | Faster loading |
Archive old logs | Keeps record storage efficient |
Add saved searches for monitoring | Quick system overview |
Use colors and icons for readability | Easier daily checks |
Conclusion
With a proper logging and monitoring dashboard, NetSuite integrations become transparent and traceable.
Admins can quickly identify failures, review performance, and take action β all within NetSuite.
The result: a self-healing, auditable, and data-driven integration environment.
Discover more from The NetSuite Pro
Subscribe to get the latest posts sent to your email.
Leave a Reply