New Relic One CDN Configuration — ตรวจสอบ CDN
New Relic CDN
New Relic One CDN Configuration Browser Monitoring Synthetic Checks APM Infrastructure TTFB Cache Hit Rate Alert Dashboard NRQL Performance Optimization
| Feature | Purpose | Data Source | Frequency | เหมาะกับ |
|---|---|---|---|---|
| Browser Monitoring | Real User Metrics | JavaScript Agent | Every page load | RUM Data |
| Synthetic Monitoring | Proactive Checks | Scripted Browser | 1-15 min interval | Uptime SLA |
| APM | Backend Performance | Language Agent | Every request | Origin Server |
| Infrastructure | Server Metrics | Infra Agent | Every 15s | Origin Infra |
| Logs | CDN Access Logs | Log Forwarder | Real-time | Troubleshooting |
Browser Monitoring Setup
=== New Relic Browser Monitoring ===
Install Browser Agent
Add this script to <head> of every page:
<script type="text/javascript">
;window.NREUM||(NREUM={});NREUM.init={distributed_tracing:{enabled:true},
privacy:{cookies_enabled:true}, ajax:{deny_list:["bam.nr-data.net"]}};
... New Relic Browser Agent code
</script>
NRQL Queries — CDN Performance
-- Page Load Time by CDN Edge
SELECT average(duration) as 'Avg Load Time',
percentile(duration, 95) as 'P95 Load Time',
count(*) as 'Page Views'
FROM PageView
WHERE appName = 'My Website'
FACET city, regionCode
SINCE 1 hour ago
-- TTFB Analysis
SELECT average(backendDuration) as 'Avg TTFB',
percentile(backendDuration, 99) as 'P99 TTFB'
FROM PageView
FACET countryCode
SINCE 24 hours ago
-- Core Web Vitals
SELECT average(largestContentfulPaint) as 'LCP',
average(firstInputDelay) as 'FID',
average(cumulativeLayoutShift) as 'CLS'
FROM PageViewTiming
WHERE appName = 'My Website'
SINCE 1 day ago TIMESERIES AUTO
-- CDN Cache Analysis (from custom attributes)
SELECT percentage(count(*), WHERE cdnCacheStatus = 'HIT') as 'Cache Hit Rate',
average(cdnResponseTime) as 'CDN Response Time'
FROM PageView
WHERE cdnCacheStatus IS NOT NULL
FACET cdnEdgeLocation
SINCE 1 hour ago
from dataclasses import dataclass
@dataclass
class CDNMetric:
metric: str
current: str
target: str
status: str
nrql: str
metrics = [
CDNMetric("Page Load Time", "1.8s", "<2s", "Good", "average(duration) FROM PageView"),
CDNMetric("TTFB (P95)", "320ms", "<500ms", "Good", "percentile(backendDuration, 95)"),
CDNMetric("LCP", "2.1s", "<2.5s", "Good", "average(largestContentfulPaint)"),
CDNMetric("FID", "45ms", "<100ms", "Good", "average(firstInputDelay)"),
CDNMetric("CLS", "0.08", "<0.1", "Good", "average(cumulativeLayoutShift)"),
CDNMetric("Cache Hit Rate", "92%", ">90%", "Good", "percentage WHERE cdnCacheStatus='HIT'"),
CDNMetric("Error Rate", "0.3%", "<1%", "Good", "percentage WHERE httpResponseCode >= 400"),
]
print("=== CDN Performance Dashboard ===")
for m in metrics:
print(f" [{m.status}] {m.metric}: {m.current} (Target: {m.target})")
print(f" NRQL: {m.nrql}")
Synthetic Monitoring
=== Synthetic CDN Checks ===
Scripted Browser — Check CDN from multiple locations
Synthetic Script (Node.js)
const assert = require('assert');
Navigate to page
await $browser.get('https://www.example.com');
Check page load time
const timing = await $browser.executeScript(function() {
const perf = window.performance.timing;
return {
ttfb: perf.responseStart - perf.navigationStart,
domReady: perf.domContentLoadedEventEnd - perf.navigationStart,
loadComplete: perf.loadEventEnd - perf.navigationStart,
};
});
console.log('TTFB:', timing.ttfb, 'ms');
console.log('DOM Ready:', timing.domReady, 'ms');
console.log('Load:', timing.loadComplete, 'ms');
assert(timing.ttfb < 500, 'TTFB exceeds 500ms: ' + timing.ttfb);
assert(timing.loadComplete < 3000, 'Load exceeds 3s: ' + timing.loadComplete);
Check CDN headers
const response = await $http.get('https://cdn.example.com/main.js');
const cacheStatus = response.headers['x-cache'] || response.headers['cf-cache-status'];
console.log('Cache Status:', cacheStatus);
Check critical resources
const resources = ['main.css', 'main.js', 'hero.webp'];
for (const res of resources) {
const r = await $http.get(`https://cdn.example.com/`);
assert(r.statusCode === 200, ` returned `);
}
@dataclass
class SyntheticCheck:
name: str
check_type: str
locations: int
frequency: str
threshold: str
alert: str
checks = [
SyntheticCheck("Homepage Load", "Scripted Browser", 10, "5 min", "Load < 3s", "Critical if fail 2x"),
SyntheticCheck("API Health", "API Test", 5, "1 min", "Status 200 < 500ms", "Critical if fail 1x"),
SyntheticCheck("CDN Asset Check", "Simple Browser", 10, "5 min", "Status 200", "Warning if fail 2x"),
SyntheticCheck("SSL Certificate", "API Test", 3, "15 min", "Valid > 30 days", "Warning if < 30d"),
SyntheticCheck("DNS Resolution", "API Test", 10, "5 min", "Resolve < 50ms", "Critical if fail 3x"),
]
print("\n=== Synthetic Monitors ===")
for c in checks:
print(f" [{c.name}] {c.check_type}")
print(f" Locations: {c.locations} | Frequency: {c.frequency}")
print(f" Threshold: {c.threshold} | Alert: {c.alert}")
Alert Configuration
# === New Relic Alert Policies ===
# Create Alert Policy via NerdGraph API
# mutation {
# alertsPolicyCreate(accountId: 12345, policy: {
# name: "CDN Performance"
# incidentPreference: PER_CONDITION
# }) {
# id
# name
# }
# }
# NRQL Alert Conditions
# -- High Page Load Time
# SELECT percentile(duration, 95) FROM PageView
# WHERE appName = 'My Website'
# -- Warning: > 2s, Critical: > 3s, for 5 minutes
# -- Low Cache Hit Rate
# SELECT percentage(count(*), WHERE cdnCacheStatus = 'HIT')
# FROM PageView WHERE cdnCacheStatus IS NOT NULL
# -- Warning: < 85%, Critical: < 75%, for 15 minutes
# -- High Error Rate
# SELECT percentage(count(*), WHERE httpResponseCode >= 400)
# FROM PageView WHERE appName = 'My Website'
# -- Warning: > 1%, Critical: > 5%, for 5 minutes
# Notification Channels
# - Slack: #cdn-alerts
# - Email: ops-team@example.com
# - PagerDuty: CDN Service
# - Webhook: https://hooks.example.com/newrelic
@dataclass
class AlertCondition:
name: str
nrql: str
warning: str
critical: str
duration: str
notification: str
conditions = [
AlertCondition("High Page Load", "percentile(duration, 95) FROM PageView", "> 2s", "> 3s", "5 min", "Slack"),
AlertCondition("High TTFB", "percentile(backendDuration, 95) FROM PageView", "> 400ms", "> 800ms", "5 min", "Slack"),
AlertCondition("Low Cache Hit", "percentage(HIT) FROM PageView", "< 85%", "< 75%", "15 min", "Slack + Email"),
AlertCondition("High Error Rate", "percentage(4xx/5xx) FROM PageView", "> 1%", "> 5%", "5 min", "PagerDuty"),
AlertCondition("Synthetic Failure", "Synthetic Monitor", "1 fail", "2 fails", "N/A", "PagerDuty"),
AlertCondition("Origin Slow", "average(duration) FROM Transaction", "> 1s", "> 3s", "5 min", "Slack"),
]
print("Alert Conditions:")
for a in conditions:
print(f" [{a.name}]")
print(f" Warning: {a.warning} | Critical: {a.critical} | Duration: {a.duration}")
print(f" Notify: {a.notification}")
optimization = {
"Cache TTL": "เพิ่ม TTL สำหรับ Static Assets (1 year for versioned)",
"Compression": "Enable Brotli/Gzip ลด Transfer Size 60-80%",
"Image Format": "ใช้ WebP/AVIF แทน JPEG PNG ลด 30-50%",
"HTTP/2 Push": "Preload Critical CSS JS",
"Edge Compute": "ใช้ Cloudflare Workers Lambda@Edge",
"Prefetch": "DNS Prefetch Preconnect สำหรับ Third-party",
}
print(f"\n\nCDN Optimization Tips:")
for k, v in optimization.items():
print(f" [{k}]: {v}")
เคล็ดลับ
- RUM: ใช้ Browser Monitoring ดู Real User Metrics
- Synthetic: สร้าง Synthetic Check ทุก Critical Path
- NRQL: เรียนรู้ NRQL สร้าง Custom Dashboard
- Alert: ตั้ง Alert เฉพาะที่ต้อง Action ไม่ Alert มากจน Alert Fatigue
- Cache: ดู Cache Hit Rate ถ้าต่ำกว่า 90% ปรับ Cache Rules
New Relic One คืออะไร
Full-stack Observability APM Infrastructure Browser Synthetic Logs Alert Dashboard NRQL Free Tier 100GB/เดือน Platform เดียว