Every action will be passed a logger object in the incoming arguments. The logger conforms to the logger API and will output log statements viewable in Gadget's Logs.
Every HTTP route will be passed a request.logger object on the incoming request object which can be used during the request to write logs. The logger adheres to the logger API and displays log statements in Gadget's Logs.
routes/GET-example.js
JavaScript
module.exports=async(request, reply)=>{
logger.info({ip: request.ip},"requester ip");
// log entry will show up in the Logs
await reply.code(200).send("route response");
};
console.log
Gadget supports console.log statements for logging in your application and will show console.log messages in the Log's at the info log level.
some-model/apiCall.js
JavaScript
1exportasyncfunctionrun({ api, record, logger }){
2const result =awaitsomeAPICall();
3
4// works but is discouraged, will just log the message to the Log's
5console.log(`finished API call: ${result.statusCode}`);
6
7// works well and is encouraged, will log the message with surrounding context like the action and model, and is more performant
8 logger.info({statusCode: result.statusCode},"finished API call");
9}
Using the structured logger object is recommended over using console.log for better performance, and to allow Gadget to add more
context to your log messages.
logger API
Log messages are sent to the logger by calling one of the logging methods with an optional structured data object and a string message.
JavaScript
1// log a plain old string message at the info level
2logger.info("Hello world");
3
4// log a structured object and a message at the info level
The default log levels (and associated log functions) are trace, debug, info, warn, error, and fatal.
The passed logger object is an instance of a pino.Logger managed by the Gadget platform. View the
Pino logger docs for full API documentation.
Passing structured data
An object can optionally be supplied as the first parameter to log messages. Each key and value of the object is stringified and written to your application's logs as JSON.
JavaScript
logger.info({value:{foo:"bar"}});
Log calls at any level can also pass Error objects to get an easy-to-digest log entry in the Log Viewer for the error, including it's stack trace and any other associated details. To log Error objects, pass the object at the error key of the structured data:
Gadget logs all events in your application. Logs are queryable using LogQL, a powerful language for searching through logs.
Gadget apps utilize structured logging, where logs are JSON objects that can contain a string message and also key-value pairs of other data. console.log works like it might in the browser or node.js in other JavaScript environments, but if you want to log structured data, you can use the structured logger object passed to your action files or request.log passed to HTTP routes.
Querying for a string
To search your logs for a specific string, use the |= operator:
To search your logs for structured entries where a particular key has been set to a particular value, add a | json filter and then use the | operator to search for a particular key value pair.
Gadget will return all logs tagged with this trace ID over the searched time range. If nothing is found, you may need to expand your time ranger further to find when a particular trace was executed.
Stream selectors
Gadget logs are queryable via LogQL, which always requires a stream selector within the log query. The stream selector is the part of the query at the beginning that looks like {level="info|warn|error"}. Gadget includes a default stream selector in all generated log queries. You can modify the stream selector, but you can't omit it. If you need to restore the default stream selector in your query, click the Reset button in the query bar.
Platform Logs
Gadget emits log entries as a platform in order to keep you informed about what work Gadget is conducting within your application. Gadget emits log entries for:
Incoming requests and responses for HTTP routes
Incoming requests and responses for GraphQL API requests
Shopify Connection shop installation and uninstallation
Trace IDs
Gadget attaches a unique identifier to request called a trace ID. Every log emitted by any piece of code during that request will have the same trace ID marked on it, which allows you to find all the logs for one given request in your Logger.
Viewing all the logs for a single trace
To view the logs for one particular request through your application, and filter out all other requests, click the blue trace_id label in the logger for any log entry:
When you click a trace ID, the logger will adjust the log search query to filter out everything except logs for this particular trace. You can then use the LogQL query language to filter the logs further.
Getting the trace ID for a request
Gadget replies to each request with the trace ID in the x-trace-id header. If you use your browser's Developer Tools and look in the Network tab at a request made to the Gadget platform, you can find an x-trace-id response header showing the trace ID that Gadget assigned that request.
For requests to your app's GraphQL API, Gadget will also include an extensions property in the JSON response containing the trace_id for easy copy/pasting, as well as a direct link to the logs within your app for that trace. Requests made from any client will include this data, including your app's frontend and the Gadget GraphQL Playground. For example, this request made in the playground includes a link to the logger:
The trace ID and logs link are not sensitive data and are sent with every response. Only developers with access to your application's editor will be able to view the logs for a given trace ID.