Upload files to "load-tests"
This commit is contained in:
274
load-tests/nrql-queries.sql
Normal file
274
load-tests/nrql-queries.sql
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
-- ============================================================
|
||||||
|
-- HOALedgerIQ – New Relic NRQL Query Library
|
||||||
|
-- App name: HOALedgerIQ_App
|
||||||
|
-- Usage: Run in New Relic Query Builder. Replace time windows as needed.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 1: OVERVIEW HEALTH ────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- 1.1 Apdex score over last test window
|
||||||
|
SELECT apdex(duration, t: 0.5) AS 'Apdex'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
-- 1.2 Overall throughput (requests per minute)
|
||||||
|
SELECT rate(count(*), 1 minute) AS 'RPM'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
-- 1.3 Error rate over time
|
||||||
|
SELECT percentage(count(*), WHERE error IS true) AS 'Error %'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 2: LATENCY BY ENDPOINT ────────────────────────────────────────
|
||||||
|
|
||||||
|
-- 2.1 p50 / p95 / p99 latency by transaction name
|
||||||
|
SELECT percentile(duration, 50, 95, 99) AS 'ms'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
LIMIT 30
|
||||||
|
|
||||||
|
-- 2.2 Slowest endpoints (p95) during load test window
|
||||||
|
SELECT percentile(duration, 95) AS 'p95 ms'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
ORDER BY percentile(duration, 95) DESC
|
||||||
|
LIMIT 20
|
||||||
|
|
||||||
|
-- 2.3 Auth endpoint latency breakdown
|
||||||
|
SELECT percentile(duration, 50, 95, 99)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND name LIKE '%auth%'
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 2.4 Report endpoint latency (typically slowest reads)
|
||||||
|
SELECT percentile(duration, 50, 95, 99)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND name LIKE '%reports%'
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 2.5 Write endpoint latency (journal-entries, payments, invoices)
|
||||||
|
SELECT percentile(duration, 50, 95, 99)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND (name LIKE '%journal-entries%' OR name LIKE '%payments%' OR name LIKE '%invoices%')
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 2.6 Latency heatmap over time for dashboard load
|
||||||
|
SELECT histogram(duration, width: 100, buckets: 20)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND name LIKE '%reports/dashboard%'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 3: DATABASE PERFORMANCE ──────────────────────────────────────
|
||||||
|
|
||||||
|
-- 3.1 Slowest database queries (top 20)
|
||||||
|
SELECT average(duration) AS 'avg ms', count(*) AS 'calls'
|
||||||
|
FROM DatastoreSegment
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET statement
|
||||||
|
SINCE 1 hour ago
|
||||||
|
ORDER BY average(duration) DESC
|
||||||
|
LIMIT 20
|
||||||
|
|
||||||
|
-- 3.2 Database call count by operation type
|
||||||
|
SELECT count(*)
|
||||||
|
FROM DatastoreSegment
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET operation
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 3.3 N+1 detection – high-call-count queries
|
||||||
|
SELECT count(*) AS 'call count', average(duration) AS 'avg ms'
|
||||||
|
FROM DatastoreSegment
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET statement
|
||||||
|
SINCE 1 hour ago
|
||||||
|
ORDER BY count(*) DESC
|
||||||
|
LIMIT 20
|
||||||
|
|
||||||
|
-- 3.4 DB time as % of total transaction time (per endpoint)
|
||||||
|
SELECT average(databaseDuration) / average(duration) * 100 AS '% DB time'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND databaseDuration IS NOT NULL
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
ORDER BY average(databaseDuration) / average(duration) DESC
|
||||||
|
LIMIT 20
|
||||||
|
|
||||||
|
-- 3.5 Connection pool pressure (slow queries that may indicate pool exhaustion)
|
||||||
|
SELECT count(*) AS 'slow queries (>500ms)'
|
||||||
|
FROM DatastoreSegment
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND duration > 0.5
|
||||||
|
FACET statement
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 3.6 Multi-tenant schema switch overhead (TenantMiddleware)
|
||||||
|
SELECT average(duration) AS 'avg ms'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND name NOT LIKE '%auth/login%'
|
||||||
|
AND name NOT LIKE '%auth/refresh%'
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
ORDER BY average(duration) DESC
|
||||||
|
LIMIT 20
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 4: ERROR ANALYSIS ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- 4.1 All errors by class and message
|
||||||
|
SELECT count(*), latest(errorMessage)
|
||||||
|
FROM TransactionError
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET errorClass, errorMessage
|
||||||
|
SINCE 1 hour ago
|
||||||
|
LIMIT 30
|
||||||
|
|
||||||
|
-- 4.2 Error rate by HTTP status code
|
||||||
|
SELECT count(*)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND httpResponseCode >= 400
|
||||||
|
FACET httpResponseCode
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
-- 4.3 403 errors (WriteAccessGuard rejections under load)
|
||||||
|
SELECT count(*) AS '403 Forbidden'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND httpResponseCode = 403
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 4.4 429 errors (rate limiter – Throttler)
|
||||||
|
SELECT count(*) AS '429 Rate Limited'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND httpResponseCode = 429
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 4.5 500 errors by endpoint
|
||||||
|
SELECT count(*), latest(errorMessage)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND httpResponseCode = 500
|
||||||
|
FACET name, errorMessage
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 4.6 JWT / auth failures
|
||||||
|
SELECT count(*)
|
||||||
|
FROM TransactionError
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND (errorMessage LIKE '%jwt%' OR errorMessage LIKE '%token%' OR errorMessage LIKE '%unauthorized%')
|
||||||
|
FACET errorMessage
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 5: INFRASTRUCTURE (during test window) ───────────────────────
|
||||||
|
|
||||||
|
-- 5.1 CPU utilization
|
||||||
|
SELECT average(cpuPercent) AS 'CPU %'
|
||||||
|
FROM SystemSample
|
||||||
|
WHERE hostname LIKE '%hoaledgeriq%'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
-- 5.2 Memory utilization
|
||||||
|
SELECT average(memoryUsedPercent) AS 'Memory %'
|
||||||
|
FROM SystemSample
|
||||||
|
WHERE hostname LIKE '%hoaledgeriq%'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
-- 5.3 Network I/O
|
||||||
|
SELECT average(transmitBytesPerSecond) AS 'TX bytes/s',
|
||||||
|
average(receiveBytesPerSecond) AS 'RX bytes/s'
|
||||||
|
FROM NetworkSample
|
||||||
|
WHERE hostname LIKE '%hoaledgeriq%'
|
||||||
|
SINCE 1 hour ago
|
||||||
|
TIMESERIES 1 minute
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 6: REDIS / BULLMQ ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- 6.1 External call latency (Redis)
|
||||||
|
SELECT average(duration) AS 'avg ms', count(*) AS 'calls'
|
||||||
|
FROM ExternalSegment
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND (name LIKE '%redis%' OR host LIKE '%redis%')
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
-- 6.2 All external service latency
|
||||||
|
SELECT average(duration) AS 'avg ms', count(*) AS 'calls'
|
||||||
|
FROM ExternalSegment
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET host
|
||||||
|
SINCE 1 hour ago
|
||||||
|
ORDER BY average(duration) DESC
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 7: BASELINE COMPARISON ───────────────────────────────────────
|
||||||
|
|
||||||
|
-- 7.1 Compare this run vs last run (adjust SINCE/UNTIL for your windows)
|
||||||
|
SELECT percentile(duration, 95) AS 'p95 this run'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET name
|
||||||
|
SINCE '2025-01-01 10:00:00' UNTIL '2025-01-01 11:00:00'
|
||||||
|
-- Run again with previous window dates to compare
|
||||||
|
|
||||||
|
-- 7.2 Regression check – endpoints that crossed p95 threshold
|
||||||
|
SELECT percentile(duration, 95) AS 'p95 ms'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND percentile(duration, 95) > 800 -- adjust to your staging threshold
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
|
|
||||||
|
|
||||||
|
-- ── SECTION 8: TENANT-AWARE ANALYSIS ──────────────────────────────────────
|
||||||
|
|
||||||
|
-- 8.1 Performance by org (if orgId is in custom attributes)
|
||||||
|
SELECT percentile(duration, 95) AS 'p95 ms', count(*) AS 'requests'
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
FACET custom.orgId
|
||||||
|
SINCE 1 hour ago
|
||||||
|
LIMIT 20
|
||||||
|
|
||||||
|
-- 8.2 Transactions without orgId (potential TenantMiddleware misses)
|
||||||
|
SELECT count(*)
|
||||||
|
FROM Transaction
|
||||||
|
WHERE appName = 'HOALedgerIQ_App'
|
||||||
|
AND custom.orgId IS NULL
|
||||||
|
AND name NOT LIKE '%auth/login%'
|
||||||
|
AND name NOT LIKE '%auth/register%'
|
||||||
|
AND name NOT LIKE '%health%'
|
||||||
|
FACET name
|
||||||
|
SINCE 1 hour ago
|
||||||
15
load-tests/user-pool.csv
Normal file
15
load-tests/user-pool.csv
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
email,password,orgId,role
|
||||||
|
treasurer01@loadtest.hoaledgeriq.com,LoadTest123!,org-001,treasurer
|
||||||
|
treasurer02@loadtest.hoaledgeriq.com,LoadTest123!,org-002,treasurer
|
||||||
|
treasurer03@loadtest.hoaledgeriq.com,LoadTest123!,org-003,treasurer
|
||||||
|
admin01@loadtest.hoaledgeriq.com,LoadTest123!,org-001,admin
|
||||||
|
admin02@loadtest.hoaledgeriq.com,LoadTest123!,org-002,admin
|
||||||
|
president01@loadtest.hoaledgeriq.com,LoadTest123!,org-001,president
|
||||||
|
president02@loadtest.hoaledgeriq.com,LoadTest123!,org-002,president
|
||||||
|
manager01@loadtest.hoaledgeriq.com,LoadTest123!,org-003,manager
|
||||||
|
manager02@loadtest.hoaledgeriq.com,LoadTest123!,org-004,manager
|
||||||
|
viewer01@loadtest.hoaledgeriq.com,LoadTest123!,org-001,viewer
|
||||||
|
viewer02@loadtest.hoaledgeriq.com,LoadTest123!,org-002,viewer
|
||||||
|
homeowner01@loadtest.hoaledgeriq.com,LoadTest123!,org-001,homeowner
|
||||||
|
homeowner02@loadtest.hoaledgeriq.com,LoadTest123!,org-002,homeowner
|
||||||
|
member01@loadtest.hoaledgeriq.com,LoadTest123!,org-001,member_at_large
|
||||||
|
Reference in New Issue
Block a user