or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aws-lambda.mdbrowser-monitoring.mdcustom-attributes.mdcustom-instrumentation.mddistributed-tracing.mderror-handling.mdindex.mdllm-monitoring.mdmetrics-events.mdsegments-timing.mdtransaction-management.mdurl-naming-rules.mdutilities.md

segments-timing.mddocs/

0

# Segments & Timing

1

2

Create custom timing segments for specific operations and code blocks within transactions.

3

4

## Capabilities

5

6

### Start Segment

7

8

Wrap a function in a segment to track its execution time and optionally record it as a metric.

9

10

```javascript { .api }

11

/**

12

* Wraps a function in a segment for custom timing. Must be called within an active transaction.

13

* @param {string} name - The name for the segment and optional metric

14

* @param {boolean} record - Whether to record the segment as a metric

15

* @param {Function} handler - The function to track as a segment

16

* @param {Function} [callback] - Optional callback for async operations

17

* @returns {*} The return value of the handler function

18

*/

19

function startSegment(name, record, handler, callback);

20

```

21

22

**Usage Examples:**

23

24

```javascript

25

const newrelic = require('newrelic');

26

27

// Simple synchronous segment

28

function processData(data) {

29

return newrelic.startSegment('DataProcessing', true, () => {

30

// This work will be timed and recorded as a metric

31

return performExpensiveCalculation(data);

32

});

33

}

34

35

// Asynchronous segment with callback

36

function fetchUserData(userId, callback) {

37

newrelic.startSegment('FetchUser', true, (cb) => {

38

database.getUser(userId, cb);

39

}, callback);

40

}

41

42

// Asynchronous segment with promises

43

async function processOrder(orderId) {

44

return newrelic.startSegment('OrderProcessing', true, async () => {

45

const order = await database.getOrder(orderId);

46

const processed = await processPayment(order);

47

await updateInventory(order.items);

48

return processed;

49

});

50

}

51

52

// Segment without metric recording (for tracing only)

53

function validateInput(input) {

54

return newrelic.startSegment('InputValidation', false, () => {

55

return validator.validate(input);

56

});

57

}

58

```

59

60

## Segment Behavior

61

62

### Recording vs. Non-Recording Segments

63

64

- **Recording segments** (`record: true`): Create metrics that appear in transaction breakdown and server breakdown graphs

65

- **Non-recording segments** (`record: false`): Only appear in transaction traces for detailed timing information

66

67

### Automatic Timing

68

69

Segments automatically:

70

- Start timing when the handler function begins execution

71

- End timing when the handler function completes

72

- Handle both synchronous and asynchronous operations

73

- Preserve return values and thrown exceptions

74

75

### Context Requirements

76

77

- Must be called within an active transaction

78

- If called outside a transaction, the handler executes normally but no segment is created

79

- Warning is logged when called outside transaction context

80

81

## Common Usage Patterns

82

83

### Database Operation Timing

84

85

```javascript

86

async function getUserWithProfile(userId) {

87

const user = await newrelic.startSegment('Database/GetUser', true, async () => {

88

return await database.users.findById(userId);

89

});

90

91

const profile = await newrelic.startSegment('Database/GetProfile', true, async () => {

92

return await database.profiles.findByUserId(userId);

93

});

94

95

return { user, profile };

96

}

97

```

98

99

### External Service Calls

100

101

```javascript

102

async function callPaymentService(paymentData) {

103

return newrelic.startSegment('External/PaymentService', true, async () => {

104

const response = await httpClient.post('/api/payments', paymentData);

105

return response.data;

106

});

107

}

108

109

async function callMultipleServices(data) {

110

const [userService, orderService, notificationService] = await Promise.all([

111

newrelic.startSegment('External/UserService', true, () =>

112

userServiceClient.updateUser(data.user)

113

),

114

newrelic.startSegment('External/OrderService', true, () =>

115

orderServiceClient.createOrder(data.order)

116

),

117

newrelic.startSegment('External/NotificationService', true, () =>

118

notificationClient.sendEmail(data.notification)

119

)

120

]);

121

122

return { userService, orderService, notificationService };

123

}

124

```

125

126

### Complex Business Logic Timing

127

128

```javascript

129

async function processComplexWorkflow(workflowData) {

130

// Validate input (trace only, no metric)

131

const validatedData = newrelic.startSegment('Workflow/Validation', false, () => {

132

return validateWorkflowData(workflowData);

133

});

134

135

// Initialize workflow (recorded as metric)

136

const workflow = await newrelic.startSegment('Workflow/Initialize', true, async () => {

137

return await initializeWorkflow(validatedData);

138

});

139

140

// Execute each step with timing

141

const results = [];

142

for (let i = 0; i < workflow.steps.length; i++) {

143

const step = workflow.steps[i];

144

const result = await newrelic.startSegment(`Workflow/Step${i + 1}`, true, async () => {

145

return await executeWorkflowStep(step, results);

146

});

147

results.push(result);

148

}

149

150

// Finalize workflow

151

return newrelic.startSegment('Workflow/Finalize', true, async () => {

152

return await finalizeWorkflow(workflow, results);

153

});

154

}

155

```

156

157

### Cache Operations

158

159

```javascript

160

async function getCachedData(key) {

161

// Check cache (trace timing but don't record as metric)

162

let data = newrelic.startSegment('Cache/Get', false, () => {

163

return cache.get(key);

164

});

165

166

if (!data) {

167

// Cache miss - fetch from database (record as metric)

168

data = await newrelic.startSegment('Database/FetchForCache', true, async () => {

169

return await database.getData(key);

170

});

171

172

// Store in cache (trace only)

173

newrelic.startSegment('Cache/Set', false, () => {

174

cache.set(key, data, 3600); // 1 hour TTL

175

});

176

}

177

178

return data;

179

}

180

```

181

182

### File System Operations

183

184

```javascript

185

const fs = require('fs').promises;

186

187

async function processFile(filePath) {

188

// Read file with timing

189

const content = await newrelic.startSegment('FileSystem/Read', true, async () => {

190

return await fs.readFile(filePath, 'utf8');

191

});

192

193

// Process content

194

const processed = newrelic.startSegment('FileProcessing/Parse', true, () => {

195

return parseFileContent(content);

196

});

197

198

// Transform data

199

const transformed = newrelic.startSegment('FileProcessing/Transform', true, () => {

200

return transformData(processed);

201

});

202

203

// Write result

204

await newrelic.startSegment('FileSystem/Write', true, async () => {

205

const outputPath = filePath.replace('.input', '.output');

206

return await fs.writeFile(outputPath, JSON.stringify(transformed));

207

});

208

209

return transformed;

210

}

211

```

212

213

### CPU-Intensive Operations

214

215

```javascript

216

function performAnalytics(dataset) {

217

// Data preparation

218

const prepared = newrelic.startSegment('Analytics/DataPrep', true, () => {

219

return dataset.map(item => normalizeData(item));

220

});

221

222

// Statistical calculations

223

const stats = newrelic.startSegment('Analytics/Statistics', true, () => {

224

return {

225

mean: calculateMean(prepared),

226

median: calculateMedian(prepared),

227

standardDeviation: calculateStdDev(prepared)

228

};

229

});

230

231

// Generate report

232

const report = newrelic.startSegment('Analytics/ReportGeneration', true, () => {

233

return generateAnalyticsReport(prepared, stats);

234

});

235

236

return report;

237

}

238

```

239

240

### Error Handling in Segments

241

242

```javascript

243

async function robustOperation(data) {

244

try {

245

return await newrelic.startSegment('RobustOperation/Execute', true, async () => {

246

const validated = validateData(data);

247

const processed = await processData(validated);

248

return processed;

249

});

250

} catch (error) {

251

// Errors are automatically captured by the segment

252

// Add additional context if needed

253

newrelic.addCustomAttribute('operationFailed', true);

254

newrelic.noticeError(error, {

255

operation: 'RobustOperation',

256

dataSize: data?.length || 0

257

});

258

throw error;

259

}

260

}

261

```

262

263

### Nested Segments

264

265

```javascript

266

async function nestedOperations(data) {

267

return newrelic.startSegment('MainOperation', true, async () => {

268

269

// Level 1 nested segment

270

const prepared = await newrelic.startSegment('MainOperation/Preparation', true, async () => {

271

272

// Level 2 nested segments

273

const cleaned = newrelic.startSegment('Preparation/DataCleaning', false, () => {

274

return cleanData(data);

275

});

276

277

const validated = newrelic.startSegment('Preparation/Validation', false, () => {

278

return validateData(cleaned);

279

});

280

281

return { cleaned, validated };

282

});

283

284

// Another level 1 segment

285

const result = await newrelic.startSegment('MainOperation/Processing', true, async () => {

286

return await processData(prepared.validated);

287

});

288

289

return result;

290

});

291

}

292

```

293

294

### Conditional Segment Recording

295

296

```javascript

297

function adaptiveSegmentRecording(data, options = {}) {

298

const shouldRecord = options.recordMetrics !== false;

299

const segmentName = options.segmentName || 'AdaptiveOperation';

300

301

return newrelic.startSegment(segmentName, shouldRecord, () => {

302

if (data.length > 1000) {

303

// For large datasets, add sub-segments

304

return newrelic.startSegment(`${segmentName}/LargeDataset`, shouldRecord, () => {

305

return processLargeDataset(data);

306

});

307

} else {

308

return processSmallDataset(data);

309

}

310

});

311

}

312

```