SiamCafe · Blog
New Relic One CDN Configuration — ตรวจสอบ CDN
บทความ

New Relic One CDN Configuration — ตรวจสอบ CDN

เผยแพร่ 28 พฤษภาคม 2569

New Relic CDN

New Relic One CDN Configuration Browser Monitoring Synthetic Checks APM Infrastructure TTFB Cache Hit Rate Alert Dashboard NRQL Performance Optimization

FeaturePurposeData SourceFrequencyเหมาะกับ
Browser MonitoringReal User MetricsJavaScript AgentEvery page loadRUM Data
Synthetic MonitoringProactive ChecksScripted Browser1-15 min intervalUptime SLA
APMBackend PerformanceLanguage AgentEvery requestOrigin Server
InfrastructureServer MetricsInfra AgentEvery 15sOrigin Infra
LogsCDN Access LogsLog ForwarderReal-timeTroubleshooting

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 เดียว