diff --git a/API.md b/API.md
index 052b32075..b2590a2c3 100644
--- a/API.md
+++ b/API.md
@@ -2913,9 +2913,10 @@ new sources.NpmJs(props?: NpmJsProps)
| bind | Binds the package source to a scope and target queue. |
| metricBatchProcessingTime | The average time it took to process a changes batch. |
| metricChangeCount | The total count of changes that were processed. |
+| metricFailedPackumentRetrievals | The number of packument checks where the registry did not serve the revision the `_changes` feed announced: it served an older one, had no packument, or could not be reached. |
| metricLaggyPackumentGiveUps | The number of laggy packuments given up on: the registry never served the revision announced by the `_changes` feed within the maximum retry age. |
| metricLaggyPackumentLag | How long laggy packuments took to catch up (or until they were given up on), measured from when the follower first saw them. |
-| metricLaggyPackuments | The number of requests in the packument queue, for laggy and missing packuments. |
+| metricLaggyPackuments | The number of change entries for which the registry served an older packument revision than the `_changes` feed announced. |
| metricLaggyPackumentsRecovered | The number of laggy packuments for which the registry caught up with the revision announced by the `_changes` feed. |
| metricLastSeq | The last sequence number that was processed. |
| metricLateChangeCount | The number of change entries discovered by a scan that were inserted into the `_changes` feed behind a position the follower had already read past. |
@@ -2927,6 +2928,8 @@ new sources.NpmJs(props?: NpmJsProps)
| metricNpmJsChangeAge | *No description.* |
| metricPackageVersionAge | The age of the oldest package version that was processed. |
| metricPackageVersionCount | The total count of package versions that were inspected. |
+| metricPackumentDelay | For packuments the registry served only after earlier checks failed: how long that took, in seconds, from when the follower read the change entry. |
+| metricPackumentGiveUps | The number of packument requests given up on, because the registry still had not served the announced revision after a day. |
| metricRelevantPackageVersions | The total count of package versions that were deemed relevant. |
| metricRemainingTime | The amount of time that was remaining when the lambda returned in order to avoid hitting a timeout. |
| metricUnprocessableEntity | The amount of changes that were not processed due to having an invalid format. |
@@ -2981,7 +2984,24 @@ The total count of changes that were processed.
---
-##### `metricLaggyPackumentGiveUps`
+##### `metricFailedPackumentRetrievals`
+
+```typescript
+public metricFailedPackumentRetrievals(opts?: MetricOptions): Metric
+```
+
+The number of packument checks where the registry did not serve the revision the `_changes` feed announced: it served an older one, had no packument, or could not be reached.
+
+Every check counts, so this shows
+registry trouble while it happens.
+
+###### `opts`Optional
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.MetricOptions
+
+---
+
+##### ~~`metricLaggyPackumentGiveUps`~~
```typescript
public metricLaggyPackumentGiveUps(opts?: MetricOptions): Metric
@@ -2998,7 +3018,7 @@ the affected package publishes again.
---
-##### `metricLaggyPackumentLag`
+##### ~~`metricLaggyPackumentLag`~~
```typescript
public metricLaggyPackumentLag(opts?: MetricOptions): Metric
@@ -3012,16 +3032,17 @@ How long laggy packuments took to catch up (or until they were given up on), mea
---
-##### `metricLaggyPackuments`
+##### ~~`metricLaggyPackuments`~~
```typescript
public metricLaggyPackuments(opts?: MetricOptions): Metric
```
-The number of requests in the packument queue, for laggy and missing packuments.
+The number of change entries for which the registry served an older packument revision than the `_changes` feed announced.
-A package that lagged in several change entries has several
-requests.
+The served
+versions are processed; the packument processor keeps re-checking for
+the announced revision.
###### `opts`Optional
@@ -3029,7 +3050,7 @@ requests.
---
-##### `metricLaggyPackumentsRecovered`
+##### ~~`metricLaggyPackumentsRecovered`~~
```typescript
public metricLaggyPackumentsRecovered(opts?: MetricOptions): Metric
@@ -3108,7 +3129,7 @@ later scan retries them.
---
-##### `metricMissingPackumentGiveUps`
+##### ~~`metricMissingPackumentGiveUps`~~
```typescript
public metricMissingPackumentGiveUps(opts?: MetricOptions): Metric
@@ -3125,7 +3146,7 @@ change entry for a package that no longer exists.
---
-##### `metricMissingPackuments`
+##### ~~`metricMissingPackuments`~~
```typescript
public metricMissingPackuments(opts?: MetricOptions): Metric
@@ -3142,7 +3163,7 @@ registry yet; the packument processor keeps re-checking for it.
---
-##### `metricMissingPackumentsRecovered`
+##### ~~`metricMissingPackumentsRecovered`~~
```typescript
public metricMissingPackumentsRecovered(opts?: MetricOptions): Metric
@@ -3196,6 +3217,41 @@ The total count of package versions that were inspected.
---
+##### `metricPackumentDelay`
+
+```typescript
+public metricPackumentDelay(opts?: MetricOptions): Metric
+```
+
+For packuments the registry served only after earlier checks failed: how long that took, in seconds, from when the follower read the change entry.
+
+###### `opts`Optional
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.MetricOptions
+
+---
+
+##### `metricPackumentGiveUps`
+
+```typescript
+public metricPackumentGiveUps(opts?: MetricOptions): Metric
+```
+
+The number of packument requests given up on, because the registry still had not served the announced revision after a day.
+
+A version announced by
+the `_changes` feed may be missing until the package publishes again.
+
+This is the total. For one reason, pass `dimensionsMap: { Reason }` with
+`Laggy` (an older revision), `Missing` (no packument) or `Unreachable`
+(the registry could not be reached), as found by the last check.
+
+###### `opts`Optional
+
+- *Type:* aws-cdk-lib.aws_cloudwatch.MetricOptions
+
+---
+
##### `metricRelevantPackageVersions`
```typescript
diff --git a/docs/application-overview.md b/docs/application-overview.md
index 225fd8b40..847fc0eae 100644
--- a/docs/application-overview.md
+++ b/docs/application-overview.md
@@ -37,16 +37,18 @@ ConstructHub provides two package source implementations: `NpmJs` and
`CodeArtifact`.
* The `NpmJs` source interfaces with the `npmjs.com` CouchDB replica (which is
- at `replicate.npmjs.com/registry`) by scanning it's `_changes` stream in
- search of relevant packages. When such a package is identified, a stager
- function is invoked, which stages the package tarball into an S3 bucket then
- notifies the ConstructHub ingestion SQS queue. The CouchDB follower is
- scheduled to run every `5 minutes`, and stores its state (receipts for the
- change entries received, and time/sequence checkpoints) in a specific object
- in the S3 bucket used for staging package tarballs.
+ at `replicate.npmjs.com/registry`) by scanning it's `_changes` stream.
+ The CouchDB follower is scheduled to run every `5 minutes`. It sends every
+ new change entry to a queue, and stores its state (receipts for the change
+ entries received, and time/sequence checkpoints) in a specific object in the
+ S3 bucket used for staging package tarballs.
+ A packument processor function works through the queue. It fetches each
+ package from `registry.npmjs.org`, and for every relevant package version, a
+ stager function is invoked, which stages the package tarball into an S3
+ bucket then notifies the ConstructHub ingestion SQS queue.
When the registry serves an older revision of a package than the feed
- announced, the package is sent to a queue, and a packument processor function
- checks it again, with growing waits, for about a day.
+ announced, or no packument at all yet, the processor checks it again, with
+ growing waits. After a day it gives up on the package.
The package versions it has processed are recorded in a DynamoDB table, so
each version is only processed once.
Existing deployments kept this list in the S3 bucket; it is copied to the
diff --git a/docs/npm-sync-protocol.md b/docs/npm-sync-protocol.md
index 2350d460a..6ab8356c0 100644
--- a/docs/npm-sync-protocol.md
+++ b/docs/npm-sync-protocol.md
@@ -114,18 +114,19 @@ The pre-migration feed also once froze its `update_seq` entirely for hours ([stu
## How ConstructHub compensates
-The *NpmJs Follower* runs on a regular schedule and fetches packuments from the registry to identify new versions.
-It does not track a single high-water mark:
+The *NpmJs Follower* runs on a regular schedule and reads the changes feed.
+It sends every change entry to a queue, where the *Packument Processor* fetches the packument from the registry to identify new versions.
+The follower does not track a single high-water mark:
it keeps a receipt for every change entry it has received,
and every run re-reads a trailing window of the feed,
-processing any entry it has no receipt for.
+sending any entry it has no receipt for.
Rolling checkpoints map times to feed positions, and derive the window's starting position.
On top of that baseline, each gap has a dedicated mitigation:
| Gap | Mitigation | Detection |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Late insertion | Every scan re-covers the trailing window; a periodic deep scan covers the full state retention | `LateChangeCount` / `LateChangeLag` metrics; `LateChangeLagHigh` alarm |
-| Laggy packuments | Process every packument the registry serves immediately; queue a re-check of the announced revision (also when the registry has no packument yet), retried with back-off for about 29 hours, then given up on | `LaggyPackuments` / `LaggyPackumentsRecovered` / `LaggyPackumentGiveUps` / `LaggyPackumentLag` and `MissingPackuments` / `MissingPackumentsRecovered` / `MissingPackumentGiveUps` metrics; `LaggyPackumentLagHigh` and `MissingPackumentsHigh` alarms |
+| Laggy packuments | Process every packument the registry serves immediately; queue a re-check of the announced revision (also when the registry has no packument yet), retried with back-off for a day, then given up on | `FailedPackumentRetrievals`, `PackumentGiveUps` (by `Reason`) and `PackumentDelay` metrics; `PendingPackumentsHigh` and `LaggyPackumentLagHigh` alarms |
| Lost events | None possible; the missed versions self-heal on the package's next publish | Package canary (`Canary/SLA-Breached`) covers the probe package |
| Head regression | The follower discards its position state and reseeds at the new head when the feed head drops below its newest checkpoint | `LastSeq` metric |
@@ -155,6 +156,7 @@ A consumer that never re-reads previously covered ranges has no way to notice th
- Operator runbook sections for the alarms named above: [operator-runbook.md](./operator-runbook.md)
- Follower implementation: `src/package-sources/npmjs/npm-js-follower.lambda.ts`
+- Packument processor implementation: `src/package-sources/npmjs/packument-processor.lambda.ts`
- Incident that motivated the windowed scan: internal reference V2376798198 *(our observation)*
[152515]: https://github.com/orgs/community/discussions/152515
diff --git a/docs/operator-runbook.md b/docs/operator-runbook.md
index 69f1590ad..d012d4b30 100644
--- a/docs/operator-runbook.md
+++ b/docs/operator-runbook.md
@@ -614,47 +614,50 @@ be increased: adjust `SCAN_WINDOW_MS` in
`src/package-sources/npmjs/constants.lambda-shared.ts` (keeping it below
`STATE_RETENTION_MS`) and deploy the updated construct.
-### `ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh`
+### `ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh`
#### Description
This alarm is only provisioned when the `NpmJs` package source is configured. It
-triggers when the npm registry had no packument (HTTP 404) for an unusually high
-number of packages announced by the CouchDB `_changes` feed, within 3 hours.
-This usually means the registry has an outage, or is far behind the feed.
+triggers when an unusually high number of packages wait, for 3 hours, for the
+npm registry to serve the revision the CouchDB `_changes` feed announced. This
+usually means the registry has an outage, or is far behind the feed.
#### Investigation
-The *NpmJs Follower* fetches package metadata from `registry.npmjs.org` for
-each change announced by the CouchDB `_changes` feed. Some of these always
-return 404, usually because a new package has not replicated to the registry
-yet (a *missing* packument). The follower sends them to the *Packument Queue*,
-where the *Packument Processor* checks them again with growing waits, for about
-a day. A normal 3 hour window has a couple of hundred of them.
+The *NpmJs Follower* sends each change announced by the CouchDB `_changes`
+feed to the *Packument Queue*, and the *Packument Processor* fetches the
+package from `registry.npmjs.org`. When the registry serves an older revision,
+no packument at all (HTTP 404, usually a new package that has not replicated
+yet), or cannot be reached, the request waits in the queue for its next check,
+with growing waits, for up to a day. Each waiting request is one package. A
+normal day has a few hundred of them.
-Check the `Missing Packuments` line on the *Feed Reliability* graph of the
-backend dashboard, and pick a few affected packages from the logs of the
-*NpmJs Follower* (`the registry has no packument for it yet`). Verify whether
-the registry serves them now:
+Check the `Waiting for next attempt` line on the *Packument Queue* graph, and
+the `Failed Packument Retrievals` line on the *Feed Reliability* graph of the
+backend dashboard. Pick a few affected packages from the logs of the
+*Packument Processor* (`checking again later`), and verify what the registry
+serves now:
```console
$ curl -s -o /dev/null -w '%{http_code}\n' https://registry.npmjs.org/
+$ curl -s https://registry.npmjs.org/ | jq ._rev
```
-If most still return 404 while the feed keeps announcing them, the problem is
-with upstream npmjs.com. Look at `npmjs.com` status updates and announcements.
-If you suspect the problem is with upstream npmjs.com, you can cut them a
-ticket. Log in to , visit the
+If most are still missing or behind while the feed keeps announcing them, the
+problem is with upstream npmjs.com. Look at `npmjs.com` status updates and
+announcements. If you suspect the problem is with upstream npmjs.com, you can
+cut them a ticket. Log in to , visit the
[Support Page](https://www.npmjs.com/support) and select
*There is a problem with the npm registry*.
#### Resolution
The packument processor processes the packages once the registry serves them.
-Packages it gives up on are logged (`Giving up on missing packument`) and then
-dropped. They show up again when the package next publishes. To ingest one
-right away, invoke the *ReStagePackageVersion* Lambda function with the package
-name and version.
+Packages it gives up on are logged (`Giving up on`) and counted in the
+`PackumentGiveUps` metric, by the reason the last check found. They show up
+again when the package next publishes. To ingest one right away, invoke the
+*ReStagePackageVersion* Lambda function with the package name and version.
--------------------------------------------------------------------------------
@@ -663,8 +666,8 @@ name and version.
#### Description
This alarm is only provisioned when the `NpmJs` package source is configured. It
-triggers when laggy packuments take unusually long to catch up: in a 3 hour
-window, 90% of them took longer than 6 hours. This usually means the registry
+triggers when packuments the registry served late took unusually long: in a 3
+hour window, 90% of them took longer than 6 hours. This usually means the registry
has an outage, or is far behind the feed.
All package versions the registry did serve have been processed. However,
@@ -674,17 +677,16 @@ the registry catches up.
#### Investigation
The registry occasionally serves an older revision of a package than the
-changes feed announced (a *laggy* packument). The follower processes the
-versions that were served, and sends the package to the *Packument Queue*. The
-*Packument Processor* checks it again with growing waits, for about 29 hours,
-and reports how long each laggy packument took to catch up. Most catch up within
-minutes, and nearly all within 6 hours.
+changes feed announced (a *laggy* packument), or none at all yet. The
+*Packument Processor* processes the versions that were served, checks the
+package again with growing waits, for up to a day, and reports how long it
+took for the announced revision to arrive (`PackumentDelay`). Most arrive
+within minutes, and nearly all within 6 hours.
Check the *Packument Queue* graph of the backend dashboard for how many
-requests are waiting, and the `Laggy Packument Give-Ups` line on the
+requests are waiting, and the `Packument Give-Ups` lines on the
*Feed Reliability* graph for how many were given up on. The logs of the
-*Packument Processor* show `caught up` and `Giving up on laggy packument`
-entries. Verify what the registry serves for a few affected packages:
+*Packument Processor* show `caught up` and `Giving up on` entries. Verify what the registry serves for a few affected packages:
```console
$ curl https://registry.npmjs.org/ | jq ._rev
@@ -859,9 +861,8 @@ When documentation for a package is not available, it could be due to several re
#### Description
This alarm is only provisioned when the `NpmJs` package source is configured. It
-triggers when the *Packument Processor* function fails or times out. While it
-fails, the requests in the *Packument Queue* keep using up their attempts, so
-they can be given up on earlier than the usual 29 hours.
+triggers when the *Packument Processor* function fails or times out. Requests
+that keep failing it move to the packument dead-letter queue.
#### Investigation
@@ -872,7 +873,7 @@ that request. Time-outs usually mean the npm registry is slow to respond.
#### Resolution
-Fix the cause. Requests that were given up on in the meantime are lost. Their
+Fix the cause. Requests in the dead-letter queue are not processed again. Their
versions show up again when the packages next publish, or can be ingested
right away with the *ReStagePackageVersion* Lambda function.
diff --git a/src/__tests__/__snapshots__/construct-hub.test.ts.snap b/src/__tests__/__snapshots__/construct-hub.test.ts.snap
index b078e00ec..dd1d32921 100644
--- a/src/__tests__/__snapshots__/construct-hub.test.ts.snap
+++ b/src/__tests__/__snapshots__/construct-hub.test.ts.snap
@@ -520,19 +520,19 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Received Bytes","expression":"FILL(m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
+ "","metrics":[[{"label":"Received Bytes","expression":"FILL(maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Received Bytes","id":"m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
+ "",{"label":"Received Bytes","id":"maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Transmitted Bytes","id":"md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
+ "",{"label":"Transmitted Bytes","id":"me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Task Count","id":"mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
+ "",{"label":"Task Count","id":"me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
{
"Ref": "AWS::Region",
},
@@ -642,27 +642,27 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
@@ -670,15 +670,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Change Count","expression":"FILL(mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
+ "","metrics":[[{"label":"Change Count","expression":"FILL(m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
+ "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Late Changes","expression":"FILL(m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5","visible":false,"stat":"Sum"}],[{"label":"Laggy Packuments","expression":"FILL(m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackuments",{"label":"Laggy Packuments","id":"m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc","visible":false,"stat":"Maximum"}],[{"label":"Laggy Packuments Recovered","expression":"FILL(meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentsRecovered",{"label":"Laggy Packuments Recovered","id":"meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentGiveUps",{"label":"Laggy Packument Give-Ups","id":"m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments","expression":"FILL(m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackuments",{"label":"Missing Packuments","id":"m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments Recovered","expression":"FILL(m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentsRecovered",{"label":"Missing Packuments Recovered","id":"m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentGiveUps",{"label":"Missing Packument Give-Ups","id":"m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
+ "","metrics":[[{"label":"Late Changes","expression":"FILL(m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46","visible":false,"stat":"Sum"}],[{"label":"Failed Packument Retrievals","expression":"FILL(ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","FailedPackumentRetrievals",{"label":"Failed Packument Retrievals","id":"ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Laggy",{"label":"Laggy Packument Give-Ups","id":"md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Missing",{"label":"Missing Packument Give-Ups","id":"mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5","visible":false,"stat":"Sum"}],[{"label":"Unreachable Packument Give-Ups","expression":"FILL(m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Unreachable",{"label":"Unreachable Packument Give-Ups","id":"m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -703,25 +703,25 @@ def sort_filter_rules(json_obj):
"QueueName",
],
},
- "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentLag",{"label":"Laggy Packument Lag (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
+ "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentDelay",{"label":"Packument Delay (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":2000,"yAxis":"left"},{"color":"#ff0000","label":"Alarm","value":21600,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Seconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Visible Messages","expression":"FILL(m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
+ "","metrics":[[{"label":"Visible Messages","expression":"FILL(mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Visible Messages","id":"m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
+ "",{"label":"Visible Messages","id":"mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Invisible Messages","id":"mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
+ "",{"label":"Invisible Messages","id":"md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
@@ -767,15 +767,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -804,7 +804,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
+ "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
{
"Ref": "AWS::Region",
},
@@ -864,15 +864,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Started","expression":"FILL(m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
+ "","metrics":[[{"label":"Started","expression":"FILL(mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Started","id":"m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
+ "",{"label":"Started","id":"mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Succeeded","id":"md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
+ "",{"label":"Succeeded","id":"m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
@@ -880,23 +880,23 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Aborted","expression":"FILL(m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
+ "","metrics":[[{"label":"Aborted","expression":"FILL(mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Aborted","id":"m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
+ "",{"label":"Aborted","id":"mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Failed","id":"m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
+ "",{"label":"Failed","id":"m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Throttled","id":"m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
+ "",{"label":"Throttled","id":"me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Timed Out","id":"m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
+ "",{"label":"Timed Out","id":"m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -956,7 +956,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Rules","expression":"FILL(m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
+ "","metrics":[[{"label":"Rules","expression":"FILL(m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubDenyListPruneDeleteQueueBBF60185",
@@ -967,15 +967,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
{
"Ref": "ConstructHubPackageDataDC5EF35E",
},
@@ -999,7 +999,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with stats","expression":"FILL(m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Packages with stats","expression":"FILL(mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -1023,7 +1023,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -10024,8 +10024,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJs15A77D2D": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22",
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6",
@@ -10038,7 +10036,7 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "a33af01281f9550bce013912ae9360dbe205878277027586445831f1ef0957e6.zip",
+ "S3Key": "82b42c20ce07850910ab4a6d68075fec2f2dd7a6d296a086737a73c4df8329f5.zip",
},
"Description": "[Test/ConstructHub/Sources/NpmJs] Periodically query npmjs.com index for new packages",
"Environment": {
@@ -10047,27 +10045,13 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"BUCKET_NAME": {
"Ref": "ConstructHubSourcesNpmJsStagingBucketB286F0E6",
},
- "DENY_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubDenyListBucket1B3C2C2E",
- },
- "DENY_LIST_OBJECT_KEY": "deny-list.json",
- "FUNCTION_NAME": {
- "Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- },
- "KNOWN_VERSIONS_TABLE_NAME": {
- "Ref": "ConstructHubSourcesKnownVersions1480B28B",
- },
- "LICENSE_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubLicenseListBucket9334047F",
- },
- "LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
},
},
"Handler": "index.handler",
- "MemorySize": 10024,
+ "MemorySize": 2048,
"ReservedConcurrentExecutions": 1,
"Role": {
"Fn::GetAtt": [
@@ -10085,8 +10069,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanary5558FC45": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2",
],
@@ -10138,10 +10120,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsCanaryAlarmBE2B479E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "New versions of construct-hub-probe have been published over 5 minutes ago and are still not visible in construct hub
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
@@ -10185,10 +10163,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryFailingE338711F": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/Failing",
"ComparisonOperator": "GreaterThanThreshold",
@@ -10211,10 +10185,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryGatewayErrorsDAA2E45C": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary has been encountering consistent HTTP gateway errors when contacting npmjs servers
for an hour or more. This means the canary has been unable to evaluate SLA compliance for that much time.
@@ -10235,10 +10205,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningFCFBD0E6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/NotRunning",
"ComparisonOperator": "LessThanThreshold",
@@ -10261,10 +10227,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningOrFailing62A8E2F6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmActions": [
"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE",
@@ -10301,8 +10263,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanarySchedule4D94219F": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -10325,8 +10285,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanaryScheduleAllowEventRuleTestConstructHubSourcesNpmJsCanary47220A990ABB5DFD": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -10348,10 +10306,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -10383,10 +10337,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -10440,10 +10390,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Policy",
},
"ConstructHubSourcesNpmJsCanaryStaleCanaryPackageA4C2ACB2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The canary package construct-hub-probe has not published a new version in over 1 day.
This means the SLA alarm is blind — no new versions are being tracked, so SLA breaches cannot be detected.
@@ -10519,25 +10465,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::CloudWatch::Alarm",
},
- "ConstructHubSourcesNpmJsFollowerMissingPackumentsHigh0AB93A32": {
- "Properties": {
- "AlarmDescription": "The npm registry had no packument for an unusually high number of packages announced by
-the CouchDB changes feed. This usually means the registry has an outage or is far behind
-the feed. The packument processor keeps re-checking these packages.
-
-Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
- "AlarmName": "Test/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh",
- "ComparisonOperator": "GreaterThanThreshold",
- "EvaluationPeriods": 1,
- "MetricName": "MissingPackuments",
- "Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
- "Period": 10800,
- "Statistic": "Sum",
- "Threshold": 1500,
- "TreatMissingData": "notBreaching",
- },
- "Type": "AWS::CloudWatch::Alarm",
- },
"ConstructHubSourcesNpmJsFollowerNoChanges2CB08C93": {
"Properties": {
"AlarmDescription": {
@@ -10614,14 +10541,13 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationAfterFollowerUpdateDB1AA774": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJs15A77D2D",
+ "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "Event",
"ServiceToken": {
@@ -10638,14 +10564,12 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesKnownVersions1480B28B",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "RequestResponse",
"ServiceToken": {
@@ -10659,11 +10583,7 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "Custom::Trigger",
"UpdateReplacePolicy": "Delete",
},
- "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7": {
"Metadata": {
"aws:cdk:do-not-refactor": true,
},
@@ -10676,8 +10596,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionEB7112AF": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A",
],
@@ -10689,9 +10607,9 @@ Direct link to Lambda function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "7301756f4001c608471bffd8c435a6d82d1bb8be6f5c44ccba0087649bcf8bc0.zip",
+ "S3Key": "9b619d8252f69c727b70d72add5b64f237cd672709297c7f2c4f0d04abb45002.zip",
},
- "Description": "[Test/ConstructHub/Sources/NpmJs] Copies the known versions from the staging bucket to the known versions table",
+ "Description": "[Test/ConstructHub/Sources/NpmJs/KnownVersionsMigration] Copies the known versions from the staging bucket to the known versions table",
"Environment": {
"Variables": {
"BUCKET_NAME": {
@@ -10719,10 +10637,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -10754,10 +10668,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -10863,8 +10773,8 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Fn::Join": [
"",
[
- "The packument processor function is failing (errors or time-outs). Requests in the
-packument queue use up their attempts while it fails, and may be given up on early.
+ "The packument processor function is failing (errors or time-outs). Requests that keep
+failing it move to the packument dead-letter queue.
Link to the lambda function: /lambda/home#/functions/",
{
@@ -10898,19 +10808,49 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsPackumentProcessorLaggyPackumentLagHigh863AFDFC": {
"Properties": {
- "AlarmDescription": "Laggy packuments take unusually long to catch up: the npm registry serves older revisions
-than the CouchDB changes feed announced, for hours. This usually means the registry has an
-outage or is far behind the feed. The packument processor keeps re-checking these packages.
+ "AlarmDescription": "The npm registry takes unusually long to serve the revisions the CouchDB changes feed
+announced: for hours. This usually means the registry has an outage or is far behind the
+feed. The packument processor keeps re-checking these packages.
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
"AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"ExtendedStatistic": "p90",
- "MetricName": "LaggyPackumentLag",
+ "MetricName": "PackumentDelay",
"Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
"Period": 10800,
- "Threshold": 21600000,
+ "Threshold": 21600,
+ "TreatMissingData": "notBreaching",
+ },
+ "Type": "AWS::CloudWatch::Alarm",
+ },
+ "ConstructHubSourcesNpmJsPackumentProcessorPendingPackumentsHighB797F54C": {
+ "Properties": {
+ "AlarmDescription": "An unusually high number of packages wait for the npm registry to serve the revision the
+CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage
+or is far behind the feed. The packument processor keeps re-checking these packages.
+
+Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
+ "AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh",
+ "ComparisonOperator": "GreaterThanThreshold",
+ "Dimensions": [
+ {
+ "Name": "QueueName",
+ "Value": {
+ "Fn::GetAtt": [
+ "ConstructHubSourcesPackumentProcessorQueue34BDE578",
+ "QueueName",
+ ],
+ },
+ },
+ ],
+ "EvaluationPeriods": 3,
+ "MetricName": "ApproximateNumberOfMessagesNotVisible",
+ "Namespace": "AWS/SQS",
+ "Period": 3600,
+ "Statistic": "Minimum",
+ "Threshold": 2000,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
@@ -10960,10 +10900,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -10995,10 +10931,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -11077,126 +11009,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
],
},
- {
- "Action": [
- "dynamodb:BatchGetItem",
- "dynamodb:Query",
- "dynamodb:GetItem",
- "dynamodb:Scan",
- "dynamodb:ConditionCheckItem",
- "dynamodb:BatchWriteItem",
- "dynamodb:PutItem",
- "dynamodb:UpdateItem",
- "dynamodb:DeleteItem",
- "dynamodb:DescribeTable",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "dynamodb:GetRecords",
- "dynamodb:GetShardIterator",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": "lambda:InvokeFunction",
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- ":*",
- ],
- ],
- },
- ],
- },
{
"Action": [
"sqs:SendMessage",
@@ -11236,7 +11048,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "2e0070c3ad67732b1d20b42f0ebba4cac975f13681fe785dbda2a355319e1c01.zip",
+ "S3Key": "c47e2e7a8f6fed2a7f8614649353767f82be1cb59f9792de8ff448a676948125.zip",
},
"DeadLetterConfig": {
"TargetArn": {
@@ -11567,7 +11379,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Properties": {
"KmsMasterKeyId": "alias/aws/sqs",
"MessageRetentionPeriod": 1209600,
- "VisibilityTimeout": 1800,
},
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
@@ -11576,6 +11387,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
"ConstructHubLicenseListCustomResource323F0FD4",
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesPackumentProcessorFunctionServiceRoleDefaultPolicy4D1F4AD4",
"ConstructHubSourcesPackumentProcessorFunctionServiceRole384F57F3",
],
@@ -11587,7 +11399,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "630d91c0090957d6232d58ca5e9b6b0d55a2ca2b654d8ef37b7f9f20faa9697c.zip",
+ "S3Key": "6b3023d10890a8d4c79a7cb82848d9226f1fbf5196fb7c0deb2d549590bc79da.zip",
},
"Description": "[Test/ConstructHub/Sources/PackumentProcessor] Processes packages from the npm registry, retrying until the registry serves the revision announced by the changes feed",
"Environment": {
@@ -11607,12 +11419,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Ref": "ConstructHubLicenseListBucket9334047F",
},
"LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
- "PACKUMENT_DEAD_LETTER_QUEUE_ARN": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
@@ -11701,22 +11507,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
],
},
},
- {
- "Action": [
- "sqs:ReceiveMessage",
- "sqs:ChangeMessageVisibility",
- "sqs:GetQueueUrl",
- "sqs:DeleteMessage",
- "sqs:GetQueueAttributes",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- },
{
"Action": [
"dynamodb:BatchGetItem",
@@ -11849,28 +11639,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::IAM::Policy",
},
- "ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorDLQEED56E2F4AC5AB3E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
- "Properties": {
- "BatchSize": 10,
- "EventSourceArn": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- "FunctionName": {
- "Ref": "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
- },
- "FunctionResponseTypes": [
- "ReportBatchItemFailures",
- ],
- },
- "Type": "AWS::Lambda::EventSourceMapping",
- },
"ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorQueue026064FBB2863D38": {
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
@@ -11891,7 +11659,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"ReportBatchItemFailures",
],
"ScalingConfig": {
- "MaximumConcurrency": 2,
+ "MaximumConcurrency": 10,
},
},
"Type": "AWS::Lambda::EventSourceMapping",
@@ -11908,7 +11676,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Arn",
],
},
- "maxReceiveCount": 10,
+ "maxReceiveCount": 20,
},
"VisibilityTimeout": 1800,
},
@@ -15314,19 +15082,19 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Received Bytes","expression":"FILL(m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
+ "","metrics":[[{"label":"Received Bytes","expression":"FILL(maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Received Bytes","id":"m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
+ "",{"label":"Received Bytes","id":"maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Transmitted Bytes","id":"md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
+ "",{"label":"Transmitted Bytes","id":"me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Task Count","id":"mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
+ "",{"label":"Task Count","id":"me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
{
"Ref": "AWS::Region",
},
@@ -15436,27 +15204,27 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
@@ -15464,15 +15232,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Change Count","expression":"FILL(mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
+ "","metrics":[[{"label":"Change Count","expression":"FILL(m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
+ "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Late Changes","expression":"FILL(m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5","visible":false,"stat":"Sum"}],[{"label":"Laggy Packuments","expression":"FILL(m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackuments",{"label":"Laggy Packuments","id":"m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc","visible":false,"stat":"Maximum"}],[{"label":"Laggy Packuments Recovered","expression":"FILL(meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentsRecovered",{"label":"Laggy Packuments Recovered","id":"meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentGiveUps",{"label":"Laggy Packument Give-Ups","id":"m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments","expression":"FILL(m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackuments",{"label":"Missing Packuments","id":"m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments Recovered","expression":"FILL(m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentsRecovered",{"label":"Missing Packuments Recovered","id":"m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentGiveUps",{"label":"Missing Packument Give-Ups","id":"m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
+ "","metrics":[[{"label":"Late Changes","expression":"FILL(m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46","visible":false,"stat":"Sum"}],[{"label":"Failed Packument Retrievals","expression":"FILL(ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","FailedPackumentRetrievals",{"label":"Failed Packument Retrievals","id":"ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Laggy",{"label":"Laggy Packument Give-Ups","id":"md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Missing",{"label":"Missing Packument Give-Ups","id":"mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5","visible":false,"stat":"Sum"}],[{"label":"Unreachable Packument Give-Ups","expression":"FILL(m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Unreachable",{"label":"Unreachable Packument Give-Ups","id":"m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -15497,25 +15265,25 @@ def sort_filter_rules(json_obj):
"QueueName",
],
},
- "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentLag",{"label":"Laggy Packument Lag (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
+ "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentDelay",{"label":"Packument Delay (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":2000,"yAxis":"left"},{"color":"#ff0000","label":"Alarm","value":21600,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Seconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Visible Messages","expression":"FILL(m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
+ "","metrics":[[{"label":"Visible Messages","expression":"FILL(mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Visible Messages","id":"m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
+ "",{"label":"Visible Messages","id":"mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Invisible Messages","id":"mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
+ "",{"label":"Invisible Messages","id":"md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
@@ -15561,15 +15329,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -15598,7 +15366,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
+ "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
{
"Ref": "AWS::Region",
},
@@ -15658,15 +15426,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Started","expression":"FILL(m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
+ "","metrics":[[{"label":"Started","expression":"FILL(mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Started","id":"m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
+ "",{"label":"Started","id":"mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Succeeded","id":"md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
+ "",{"label":"Succeeded","id":"m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
@@ -15674,23 +15442,23 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Aborted","expression":"FILL(m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
+ "","metrics":[[{"label":"Aborted","expression":"FILL(mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Aborted","id":"m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
+ "",{"label":"Aborted","id":"mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Failed","id":"m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
+ "",{"label":"Failed","id":"m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Throttled","id":"m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
+ "",{"label":"Throttled","id":"me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Timed Out","id":"m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
+ "",{"label":"Timed Out","id":"m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -15750,7 +15518,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Rules","expression":"FILL(m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
+ "","metrics":[[{"label":"Rules","expression":"FILL(m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubDenyListPruneDeleteQueueBBF60185",
@@ -15761,15 +15529,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
{
"Ref": "ConstructHubPackageDataDC5EF35E",
},
@@ -15793,7 +15561,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with stats","expression":"FILL(m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Packages with stats","expression":"FILL(mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -15817,7 +15585,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -25192,8 +24960,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJs15A77D2D": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22",
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6",
@@ -25206,7 +24972,7 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "a33af01281f9550bce013912ae9360dbe205878277027586445831f1ef0957e6.zip",
+ "S3Key": "82b42c20ce07850910ab4a6d68075fec2f2dd7a6d296a086737a73c4df8329f5.zip",
},
"Description": "[Test/ConstructHub/Sources/NpmJs] Periodically query npmjs.com index for new packages",
"Environment": {
@@ -25215,27 +24981,13 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"BUCKET_NAME": {
"Ref": "ConstructHubSourcesNpmJsStagingBucketB286F0E6",
},
- "DENY_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubDenyListBucket1B3C2C2E",
- },
- "DENY_LIST_OBJECT_KEY": "deny-list.json",
- "FUNCTION_NAME": {
- "Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- },
- "KNOWN_VERSIONS_TABLE_NAME": {
- "Ref": "ConstructHubSourcesKnownVersions1480B28B",
- },
- "LICENSE_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubLicenseListBucket9334047F",
- },
- "LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
},
},
"Handler": "index.handler",
- "MemorySize": 10024,
+ "MemorySize": 2048,
"ReservedConcurrentExecutions": 1,
"Role": {
"Fn::GetAtt": [
@@ -25253,8 +25005,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanary5558FC45": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2",
],
@@ -25306,10 +25056,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsCanaryAlarmBE2B479E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "New versions of construct-hub-probe have been published over 5 minutes ago and are still not visible in construct hub
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
@@ -25353,10 +25099,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryFailingE338711F": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/Failing",
"ComparisonOperator": "GreaterThanThreshold",
@@ -25379,10 +25121,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryGatewayErrorsDAA2E45C": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary has been encountering consistent HTTP gateway errors when contacting npmjs servers
for an hour or more. This means the canary has been unable to evaluate SLA compliance for that much time.
@@ -25403,10 +25141,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningFCFBD0E6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/NotRunning",
"ComparisonOperator": "LessThanThreshold",
@@ -25429,10 +25163,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningOrFailing62A8E2F6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmActions": [
"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE",
@@ -25469,8 +25199,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanarySchedule4D94219F": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -25493,8 +25221,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanaryScheduleAllowEventRuleTestConstructHubSourcesNpmJsCanary47220A990ABB5DFD": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -25516,10 +25242,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -25551,10 +25273,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -25608,10 +25326,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Policy",
},
"ConstructHubSourcesNpmJsCanaryStaleCanaryPackageA4C2ACB2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The canary package construct-hub-probe has not published a new version in over 1 day.
This means the SLA alarm is blind — no new versions are being tracked, so SLA breaches cannot be detected.
@@ -25687,25 +25401,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::CloudWatch::Alarm",
},
- "ConstructHubSourcesNpmJsFollowerMissingPackumentsHigh0AB93A32": {
- "Properties": {
- "AlarmDescription": "The npm registry had no packument for an unusually high number of packages announced by
-the CouchDB changes feed. This usually means the registry has an outage or is far behind
-the feed. The packument processor keeps re-checking these packages.
-
-Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
- "AlarmName": "Test/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh",
- "ComparisonOperator": "GreaterThanThreshold",
- "EvaluationPeriods": 1,
- "MetricName": "MissingPackuments",
- "Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
- "Period": 10800,
- "Statistic": "Sum",
- "Threshold": 1500,
- "TreatMissingData": "notBreaching",
- },
- "Type": "AWS::CloudWatch::Alarm",
- },
"ConstructHubSourcesNpmJsFollowerNoChanges2CB08C93": {
"Properties": {
"AlarmDescription": {
@@ -25782,14 +25477,13 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationAfterFollowerUpdateDB1AA774": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJs15A77D2D",
+ "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "Event",
"ServiceToken": {
@@ -25806,14 +25500,12 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesKnownVersions1480B28B",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "RequestResponse",
"ServiceToken": {
@@ -25827,11 +25519,7 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "Custom::Trigger",
"UpdateReplacePolicy": "Delete",
},
- "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7": {
"Metadata": {
"aws:cdk:do-not-refactor": true,
},
@@ -25844,8 +25532,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionEB7112AF": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A",
],
@@ -25857,9 +25543,9 @@ Direct link to Lambda function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "7301756f4001c608471bffd8c435a6d82d1bb8be6f5c44ccba0087649bcf8bc0.zip",
+ "S3Key": "9b619d8252f69c727b70d72add5b64f237cd672709297c7f2c4f0d04abb45002.zip",
},
- "Description": "[Test/ConstructHub/Sources/NpmJs] Copies the known versions from the staging bucket to the known versions table",
+ "Description": "[Test/ConstructHub/Sources/NpmJs/KnownVersionsMigration] Copies the known versions from the staging bucket to the known versions table",
"Environment": {
"Variables": {
"BUCKET_NAME": {
@@ -25887,10 +25573,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -25922,10 +25604,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -26031,8 +25709,8 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Fn::Join": [
"",
[
- "The packument processor function is failing (errors or time-outs). Requests in the
-packument queue use up their attempts while it fails, and may be given up on early.
+ "The packument processor function is failing (errors or time-outs). Requests that keep
+failing it move to the packument dead-letter queue.
Link to the lambda function: /lambda/home#/functions/",
{
@@ -26066,19 +25744,49 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsPackumentProcessorLaggyPackumentLagHigh863AFDFC": {
"Properties": {
- "AlarmDescription": "Laggy packuments take unusually long to catch up: the npm registry serves older revisions
-than the CouchDB changes feed announced, for hours. This usually means the registry has an
-outage or is far behind the feed. The packument processor keeps re-checking these packages.
+ "AlarmDescription": "The npm registry takes unusually long to serve the revisions the CouchDB changes feed
+announced: for hours. This usually means the registry has an outage or is far behind the
+feed. The packument processor keeps re-checking these packages.
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
"AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"ExtendedStatistic": "p90",
- "MetricName": "LaggyPackumentLag",
+ "MetricName": "PackumentDelay",
"Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
"Period": 10800,
- "Threshold": 21600000,
+ "Threshold": 21600,
+ "TreatMissingData": "notBreaching",
+ },
+ "Type": "AWS::CloudWatch::Alarm",
+ },
+ "ConstructHubSourcesNpmJsPackumentProcessorPendingPackumentsHighB797F54C": {
+ "Properties": {
+ "AlarmDescription": "An unusually high number of packages wait for the npm registry to serve the revision the
+CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage
+or is far behind the feed. The packument processor keeps re-checking these packages.
+
+Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
+ "AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh",
+ "ComparisonOperator": "GreaterThanThreshold",
+ "Dimensions": [
+ {
+ "Name": "QueueName",
+ "Value": {
+ "Fn::GetAtt": [
+ "ConstructHubSourcesPackumentProcessorQueue34BDE578",
+ "QueueName",
+ ],
+ },
+ },
+ ],
+ "EvaluationPeriods": 3,
+ "MetricName": "ApproximateNumberOfMessagesNotVisible",
+ "Namespace": "AWS/SQS",
+ "Period": 3600,
+ "Statistic": "Minimum",
+ "Threshold": 2000,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
@@ -26128,10 +25836,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -26163,10 +25867,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -26245,126 +25945,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
],
},
- {
- "Action": [
- "dynamodb:BatchGetItem",
- "dynamodb:Query",
- "dynamodb:GetItem",
- "dynamodb:Scan",
- "dynamodb:ConditionCheckItem",
- "dynamodb:BatchWriteItem",
- "dynamodb:PutItem",
- "dynamodb:UpdateItem",
- "dynamodb:DeleteItem",
- "dynamodb:DescribeTable",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "dynamodb:GetRecords",
- "dynamodb:GetShardIterator",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": "lambda:InvokeFunction",
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- ":*",
- ],
- ],
- },
- ],
- },
{
"Action": [
"sqs:SendMessage",
@@ -26404,7 +25984,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "2e0070c3ad67732b1d20b42f0ebba4cac975f13681fe785dbda2a355319e1c01.zip",
+ "S3Key": "c47e2e7a8f6fed2a7f8614649353767f82be1cb59f9792de8ff448a676948125.zip",
},
"DeadLetterConfig": {
"TargetArn": {
@@ -26735,7 +26315,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Properties": {
"KmsMasterKeyId": "alias/aws/sqs",
"MessageRetentionPeriod": 1209600,
- "VisibilityTimeout": 1800,
},
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
@@ -26744,6 +26323,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
"ConstructHubLicenseListCustomResource323F0FD4",
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesPackumentProcessorFunctionServiceRoleDefaultPolicy4D1F4AD4",
"ConstructHubSourcesPackumentProcessorFunctionServiceRole384F57F3",
],
@@ -26755,7 +26335,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "630d91c0090957d6232d58ca5e9b6b0d55a2ca2b654d8ef37b7f9f20faa9697c.zip",
+ "S3Key": "6b3023d10890a8d4c79a7cb82848d9226f1fbf5196fb7c0deb2d549590bc79da.zip",
},
"Description": "[Test/ConstructHub/Sources/PackumentProcessor] Processes packages from the npm registry, retrying until the registry serves the revision announced by the changes feed",
"Environment": {
@@ -26775,12 +26355,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Ref": "ConstructHubLicenseListBucket9334047F",
},
"LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
- "PACKUMENT_DEAD_LETTER_QUEUE_ARN": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
@@ -26869,22 +26443,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
],
},
},
- {
- "Action": [
- "sqs:ReceiveMessage",
- "sqs:ChangeMessageVisibility",
- "sqs:GetQueueUrl",
- "sqs:DeleteMessage",
- "sqs:GetQueueAttributes",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- },
{
"Action": [
"dynamodb:BatchGetItem",
@@ -27017,28 +26575,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::IAM::Policy",
},
- "ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorDLQEED56E2F4AC5AB3E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
- "Properties": {
- "BatchSize": 10,
- "EventSourceArn": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- "FunctionName": {
- "Ref": "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
- },
- "FunctionResponseTypes": [
- "ReportBatchItemFailures",
- ],
- },
- "Type": "AWS::Lambda::EventSourceMapping",
- },
"ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorQueue026064FBB2863D38": {
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
@@ -27059,7 +26595,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"ReportBatchItemFailures",
],
"ScalingConfig": {
- "MaximumConcurrency": 2,
+ "MaximumConcurrency": 10,
},
},
"Type": "AWS::Lambda::EventSourceMapping",
@@ -27076,7 +26612,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Arn",
],
},
- "maxReceiveCount": 10,
+ "maxReceiveCount": 20,
},
"VisibilityTimeout": 1800,
},
@@ -30428,19 +29964,19 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Received Bytes","expression":"FILL(m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
+ "","metrics":[[{"label":"Received Bytes","expression":"FILL(maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Received Bytes","id":"m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
+ "",{"label":"Received Bytes","id":"maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Transmitted Bytes","id":"md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
+ "",{"label":"Transmitted Bytes","id":"me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Task Count","id":"mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
+ "",{"label":"Task Count","id":"me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
{
"Ref": "AWS::Region",
},
@@ -30550,27 +30086,27 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
@@ -30578,15 +30114,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Change Count","expression":"FILL(mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
+ "","metrics":[[{"label":"Change Count","expression":"FILL(m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
+ "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Late Changes","expression":"FILL(m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5","visible":false,"stat":"Sum"}],[{"label":"Laggy Packuments","expression":"FILL(m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackuments",{"label":"Laggy Packuments","id":"m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc","visible":false,"stat":"Maximum"}],[{"label":"Laggy Packuments Recovered","expression":"FILL(meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentsRecovered",{"label":"Laggy Packuments Recovered","id":"meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentGiveUps",{"label":"Laggy Packument Give-Ups","id":"m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments","expression":"FILL(m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackuments",{"label":"Missing Packuments","id":"m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments Recovered","expression":"FILL(m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentsRecovered",{"label":"Missing Packuments Recovered","id":"m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentGiveUps",{"label":"Missing Packument Give-Ups","id":"m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
+ "","metrics":[[{"label":"Late Changes","expression":"FILL(m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46","visible":false,"stat":"Sum"}],[{"label":"Failed Packument Retrievals","expression":"FILL(ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","FailedPackumentRetrievals",{"label":"Failed Packument Retrievals","id":"ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Laggy",{"label":"Laggy Packument Give-Ups","id":"md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Missing",{"label":"Missing Packument Give-Ups","id":"mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5","visible":false,"stat":"Sum"}],[{"label":"Unreachable Packument Give-Ups","expression":"FILL(m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Unreachable",{"label":"Unreachable Packument Give-Ups","id":"m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -30611,25 +30147,25 @@ def sort_filter_rules(json_obj):
"QueueName",
],
},
- "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentLag",{"label":"Laggy Packument Lag (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
+ "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentDelay",{"label":"Packument Delay (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":2000,"yAxis":"left"},{"color":"#ff0000","label":"Alarm","value":21600,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Seconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Visible Messages","expression":"FILL(m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
+ "","metrics":[[{"label":"Visible Messages","expression":"FILL(mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Visible Messages","id":"m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
+ "",{"label":"Visible Messages","id":"mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Invisible Messages","id":"mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
+ "",{"label":"Invisible Messages","id":"md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
@@ -30675,15 +30211,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -30712,7 +30248,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
+ "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
{
"Ref": "AWS::Region",
},
@@ -30772,15 +30308,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Started","expression":"FILL(m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
+ "","metrics":[[{"label":"Started","expression":"FILL(mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Started","id":"m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
+ "",{"label":"Started","id":"mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Succeeded","id":"md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
+ "",{"label":"Succeeded","id":"m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
@@ -30788,23 +30324,23 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Aborted","expression":"FILL(m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
+ "","metrics":[[{"label":"Aborted","expression":"FILL(mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Aborted","id":"m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
+ "",{"label":"Aborted","id":"mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Failed","id":"m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
+ "",{"label":"Failed","id":"m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Throttled","id":"m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
+ "",{"label":"Throttled","id":"me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Timed Out","id":"m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
+ "",{"label":"Timed Out","id":"m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -30864,7 +30400,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Rules","expression":"FILL(m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
+ "","metrics":[[{"label":"Rules","expression":"FILL(m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubDenyListPruneDeleteQueueBBF60185",
@@ -30875,15 +30411,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
{
"Ref": "ConstructHubPackageDataDC5EF35E",
},
@@ -30907,7 +30443,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with stats","expression":"FILL(m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Packages with stats","expression":"FILL(mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -30931,7 +30467,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -39932,8 +39468,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJs15A77D2D": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22",
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6",
@@ -39946,7 +39480,7 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "a33af01281f9550bce013912ae9360dbe205878277027586445831f1ef0957e6.zip",
+ "S3Key": "82b42c20ce07850910ab4a6d68075fec2f2dd7a6d296a086737a73c4df8329f5.zip",
},
"Description": "[Test/ConstructHub/Sources/NpmJs] Periodically query npmjs.com index for new packages",
"Environment": {
@@ -39955,27 +39489,13 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"BUCKET_NAME": {
"Ref": "ConstructHubSourcesNpmJsStagingBucketB286F0E6",
},
- "DENY_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubDenyListBucket1B3C2C2E",
- },
- "DENY_LIST_OBJECT_KEY": "deny-list.json",
- "FUNCTION_NAME": {
- "Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- },
- "KNOWN_VERSIONS_TABLE_NAME": {
- "Ref": "ConstructHubSourcesKnownVersions1480B28B",
- },
- "LICENSE_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubLicenseListBucket9334047F",
- },
- "LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
},
},
"Handler": "index.handler",
- "MemorySize": 10024,
+ "MemorySize": 2048,
"ReservedConcurrentExecutions": 1,
"Role": {
"Fn::GetAtt": [
@@ -39993,8 +39513,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanary5558FC45": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2",
],
@@ -40046,10 +39564,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsCanaryAlarmBE2B479E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "New versions of construct-hub-probe have been published over 5 minutes ago and are still not visible in construct hub
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
@@ -40093,10 +39607,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryFailingE338711F": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/Failing",
"ComparisonOperator": "GreaterThanThreshold",
@@ -40119,10 +39629,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryGatewayErrorsDAA2E45C": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary has been encountering consistent HTTP gateway errors when contacting npmjs servers
for an hour or more. This means the canary has been unable to evaluate SLA compliance for that much time.
@@ -40143,10 +39649,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningFCFBD0E6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/NotRunning",
"ComparisonOperator": "LessThanThreshold",
@@ -40169,10 +39671,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningOrFailing62A8E2F6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmActions": [
"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE",
@@ -40209,8 +39707,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanarySchedule4D94219F": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -40233,8 +39729,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanaryScheduleAllowEventRuleTestConstructHubSourcesNpmJsCanary47220A990ABB5DFD": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -40256,10 +39750,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -40291,10 +39781,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -40348,10 +39834,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Policy",
},
"ConstructHubSourcesNpmJsCanaryStaleCanaryPackageA4C2ACB2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The canary package construct-hub-probe has not published a new version in over 1 day.
This means the SLA alarm is blind — no new versions are being tracked, so SLA breaches cannot be detected.
@@ -40427,25 +39909,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::CloudWatch::Alarm",
},
- "ConstructHubSourcesNpmJsFollowerMissingPackumentsHigh0AB93A32": {
- "Properties": {
- "AlarmDescription": "The npm registry had no packument for an unusually high number of packages announced by
-the CouchDB changes feed. This usually means the registry has an outage or is far behind
-the feed. The packument processor keeps re-checking these packages.
-
-Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
- "AlarmName": "Test/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh",
- "ComparisonOperator": "GreaterThanThreshold",
- "EvaluationPeriods": 1,
- "MetricName": "MissingPackuments",
- "Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
- "Period": 10800,
- "Statistic": "Sum",
- "Threshold": 1500,
- "TreatMissingData": "notBreaching",
- },
- "Type": "AWS::CloudWatch::Alarm",
- },
"ConstructHubSourcesNpmJsFollowerNoChanges2CB08C93": {
"Properties": {
"AlarmDescription": {
@@ -40522,14 +39985,13 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationAfterFollowerUpdateDB1AA774": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJs15A77D2D",
+ "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "Event",
"ServiceToken": {
@@ -40546,14 +40008,12 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesKnownVersions1480B28B",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "RequestResponse",
"ServiceToken": {
@@ -40567,11 +40027,7 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "Custom::Trigger",
"UpdateReplacePolicy": "Delete",
},
- "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7": {
"Metadata": {
"aws:cdk:do-not-refactor": true,
},
@@ -40584,8 +40040,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionEB7112AF": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A",
],
@@ -40597,9 +40051,9 @@ Direct link to Lambda function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "7301756f4001c608471bffd8c435a6d82d1bb8be6f5c44ccba0087649bcf8bc0.zip",
+ "S3Key": "9b619d8252f69c727b70d72add5b64f237cd672709297c7f2c4f0d04abb45002.zip",
},
- "Description": "[Test/ConstructHub/Sources/NpmJs] Copies the known versions from the staging bucket to the known versions table",
+ "Description": "[Test/ConstructHub/Sources/NpmJs/KnownVersionsMigration] Copies the known versions from the staging bucket to the known versions table",
"Environment": {
"Variables": {
"BUCKET_NAME": {
@@ -40627,10 +40081,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -40662,10 +40112,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -40771,8 +40217,8 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Fn::Join": [
"",
[
- "The packument processor function is failing (errors or time-outs). Requests in the
-packument queue use up their attempts while it fails, and may be given up on early.
+ "The packument processor function is failing (errors or time-outs). Requests that keep
+failing it move to the packument dead-letter queue.
Link to the lambda function: /lambda/home#/functions/",
{
@@ -40806,19 +40252,49 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsPackumentProcessorLaggyPackumentLagHigh863AFDFC": {
"Properties": {
- "AlarmDescription": "Laggy packuments take unusually long to catch up: the npm registry serves older revisions
-than the CouchDB changes feed announced, for hours. This usually means the registry has an
-outage or is far behind the feed. The packument processor keeps re-checking these packages.
+ "AlarmDescription": "The npm registry takes unusually long to serve the revisions the CouchDB changes feed
+announced: for hours. This usually means the registry has an outage or is far behind the
+feed. The packument processor keeps re-checking these packages.
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
"AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"ExtendedStatistic": "p90",
- "MetricName": "LaggyPackumentLag",
+ "MetricName": "PackumentDelay",
"Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
"Period": 10800,
- "Threshold": 21600000,
+ "Threshold": 21600,
+ "TreatMissingData": "notBreaching",
+ },
+ "Type": "AWS::CloudWatch::Alarm",
+ },
+ "ConstructHubSourcesNpmJsPackumentProcessorPendingPackumentsHighB797F54C": {
+ "Properties": {
+ "AlarmDescription": "An unusually high number of packages wait for the npm registry to serve the revision the
+CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage
+or is far behind the feed. The packument processor keeps re-checking these packages.
+
+Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
+ "AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh",
+ "ComparisonOperator": "GreaterThanThreshold",
+ "Dimensions": [
+ {
+ "Name": "QueueName",
+ "Value": {
+ "Fn::GetAtt": [
+ "ConstructHubSourcesPackumentProcessorQueue34BDE578",
+ "QueueName",
+ ],
+ },
+ },
+ ],
+ "EvaluationPeriods": 3,
+ "MetricName": "ApproximateNumberOfMessagesNotVisible",
+ "Namespace": "AWS/SQS",
+ "Period": 3600,
+ "Statistic": "Minimum",
+ "Threshold": 2000,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
@@ -40868,10 +40344,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -40903,10 +40375,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -40985,126 +40453,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
],
},
- {
- "Action": [
- "dynamodb:BatchGetItem",
- "dynamodb:Query",
- "dynamodb:GetItem",
- "dynamodb:Scan",
- "dynamodb:ConditionCheckItem",
- "dynamodb:BatchWriteItem",
- "dynamodb:PutItem",
- "dynamodb:UpdateItem",
- "dynamodb:DeleteItem",
- "dynamodb:DescribeTable",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "dynamodb:GetRecords",
- "dynamodb:GetShardIterator",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": "lambda:InvokeFunction",
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- ":*",
- ],
- ],
- },
- ],
- },
{
"Action": [
"sqs:SendMessage",
@@ -41144,7 +40492,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "2e0070c3ad67732b1d20b42f0ebba4cac975f13681fe785dbda2a355319e1c01.zip",
+ "S3Key": "c47e2e7a8f6fed2a7f8614649353767f82be1cb59f9792de8ff448a676948125.zip",
},
"DeadLetterConfig": {
"TargetArn": {
@@ -41475,7 +40823,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Properties": {
"KmsMasterKeyId": "alias/aws/sqs",
"MessageRetentionPeriod": 1209600,
- "VisibilityTimeout": 1800,
},
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
@@ -41484,6 +40831,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
"ConstructHubLicenseListCustomResource323F0FD4",
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesPackumentProcessorFunctionServiceRoleDefaultPolicy4D1F4AD4",
"ConstructHubSourcesPackumentProcessorFunctionServiceRole384F57F3",
],
@@ -41495,7 +40843,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "630d91c0090957d6232d58ca5e9b6b0d55a2ca2b654d8ef37b7f9f20faa9697c.zip",
+ "S3Key": "6b3023d10890a8d4c79a7cb82848d9226f1fbf5196fb7c0deb2d549590bc79da.zip",
},
"Description": "[Test/ConstructHub/Sources/PackumentProcessor] Processes packages from the npm registry, retrying until the registry serves the revision announced by the changes feed",
"Environment": {
@@ -41515,12 +40863,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Ref": "ConstructHubLicenseListBucket9334047F",
},
"LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
- "PACKUMENT_DEAD_LETTER_QUEUE_ARN": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
@@ -41609,22 +40951,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
],
},
},
- {
- "Action": [
- "sqs:ReceiveMessage",
- "sqs:ChangeMessageVisibility",
- "sqs:GetQueueUrl",
- "sqs:DeleteMessage",
- "sqs:GetQueueAttributes",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- },
{
"Action": [
"dynamodb:BatchGetItem",
@@ -41757,28 +41083,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::IAM::Policy",
},
- "ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorDLQEED56E2F4AC5AB3E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
- "Properties": {
- "BatchSize": 10,
- "EventSourceArn": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- "FunctionName": {
- "Ref": "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
- },
- "FunctionResponseTypes": [
- "ReportBatchItemFailures",
- ],
- },
- "Type": "AWS::Lambda::EventSourceMapping",
- },
"ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorQueue026064FBB2863D38": {
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
@@ -41799,7 +41103,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"ReportBatchItemFailures",
],
"ScalingConfig": {
- "MaximumConcurrency": 2,
+ "MaximumConcurrency": 10,
},
},
"Type": "AWS::Lambda::EventSourceMapping",
@@ -41816,7 +41120,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Arn",
],
},
- "maxReceiveCount": 10,
+ "maxReceiveCount": 20,
},
"VisibilityTimeout": 1800,
},
@@ -45310,19 +44614,19 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Received Bytes","expression":"FILL(m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
+ "","metrics":[[{"label":"Received Bytes","expression":"FILL(maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Received Bytes","id":"m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
+ "",{"label":"Received Bytes","id":"maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Transmitted Bytes","id":"md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
+ "",{"label":"Transmitted Bytes","id":"me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Task Count","id":"mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
+ "",{"label":"Task Count","id":"me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
{
"Ref": "AWS::Region",
},
@@ -45432,27 +44736,27 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
@@ -45460,15 +44764,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Change Count","expression":"FILL(mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
+ "","metrics":[[{"label":"Change Count","expression":"FILL(m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
+ "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Late Changes","expression":"FILL(m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5","visible":false,"stat":"Sum"}],[{"label":"Laggy Packuments","expression":"FILL(m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackuments",{"label":"Laggy Packuments","id":"m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc","visible":false,"stat":"Maximum"}],[{"label":"Laggy Packuments Recovered","expression":"FILL(meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentsRecovered",{"label":"Laggy Packuments Recovered","id":"meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentGiveUps",{"label":"Laggy Packument Give-Ups","id":"m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments","expression":"FILL(m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackuments",{"label":"Missing Packuments","id":"m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments Recovered","expression":"FILL(m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentsRecovered",{"label":"Missing Packuments Recovered","id":"m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentGiveUps",{"label":"Missing Packument Give-Ups","id":"m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
+ "","metrics":[[{"label":"Late Changes","expression":"FILL(m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46","visible":false,"stat":"Sum"}],[{"label":"Failed Packument Retrievals","expression":"FILL(ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","FailedPackumentRetrievals",{"label":"Failed Packument Retrievals","id":"ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Laggy",{"label":"Laggy Packument Give-Ups","id":"md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Missing",{"label":"Missing Packument Give-Ups","id":"mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5","visible":false,"stat":"Sum"}],[{"label":"Unreachable Packument Give-Ups","expression":"FILL(m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Unreachable",{"label":"Unreachable Packument Give-Ups","id":"m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -45493,25 +44797,25 @@ def sort_filter_rules(json_obj):
"QueueName",
],
},
- "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentLag",{"label":"Laggy Packument Lag (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
+ "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentDelay",{"label":"Packument Delay (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":2000,"yAxis":"left"},{"color":"#ff0000","label":"Alarm","value":21600,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Seconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Visible Messages","expression":"FILL(m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
+ "","metrics":[[{"label":"Visible Messages","expression":"FILL(mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Visible Messages","id":"m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
+ "",{"label":"Visible Messages","id":"mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Invisible Messages","id":"mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
+ "",{"label":"Invisible Messages","id":"md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
@@ -45557,15 +44861,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -45594,7 +44898,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
+ "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
{
"Ref": "AWS::Region",
},
@@ -45654,15 +44958,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Started","expression":"FILL(m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
+ "","metrics":[[{"label":"Started","expression":"FILL(mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Started","id":"m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
+ "",{"label":"Started","id":"mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Succeeded","id":"md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
+ "",{"label":"Succeeded","id":"m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
@@ -45670,23 +44974,23 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Aborted","expression":"FILL(m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
+ "","metrics":[[{"label":"Aborted","expression":"FILL(mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Aborted","id":"m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
+ "",{"label":"Aborted","id":"mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Failed","id":"m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
+ "",{"label":"Failed","id":"m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Throttled","id":"m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
+ "",{"label":"Throttled","id":"me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Timed Out","id":"m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
+ "",{"label":"Timed Out","id":"m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -45746,7 +45050,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Rules","expression":"FILL(m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
+ "","metrics":[[{"label":"Rules","expression":"FILL(m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubDenyListPruneDeleteQueueBBF60185",
@@ -45757,15 +45061,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
{
"Ref": "ConstructHubPackageDataDC5EF35E",
},
@@ -45789,7 +45093,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with stats","expression":"FILL(m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Packages with stats","expression":"FILL(mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -45813,7 +45117,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -54823,8 +54127,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJs15A77D2D": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22",
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6",
@@ -54837,7 +54139,7 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "a33af01281f9550bce013912ae9360dbe205878277027586445831f1ef0957e6.zip",
+ "S3Key": "82b42c20ce07850910ab4a6d68075fec2f2dd7a6d296a086737a73c4df8329f5.zip",
},
"Description": "[Test/ConstructHub/Sources/NpmJs] Periodically query npmjs.com index for new packages",
"Environment": {
@@ -54846,27 +54148,13 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"BUCKET_NAME": {
"Ref": "ConstructHubSourcesNpmJsStagingBucketB286F0E6",
},
- "DENY_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubDenyListBucket1B3C2C2E",
- },
- "DENY_LIST_OBJECT_KEY": "deny-list.json",
- "FUNCTION_NAME": {
- "Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- },
- "KNOWN_VERSIONS_TABLE_NAME": {
- "Ref": "ConstructHubSourcesKnownVersions1480B28B",
- },
- "LICENSE_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubLicenseListBucket9334047F",
- },
- "LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
},
},
"Handler": "index.handler",
- "MemorySize": 10024,
+ "MemorySize": 2048,
"ReservedConcurrentExecutions": 1,
"Role": {
"Fn::GetAtt": [
@@ -54884,8 +54172,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanary5558FC45": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2",
],
@@ -54924,10 +54210,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsCanaryAlarmBE2B479E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "New versions of construct-hub-probe have been published over 5 minutes ago and are still not visible in construct hub
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
@@ -54971,10 +54253,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryFailingE338711F": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/Failing",
"ComparisonOperator": "GreaterThanThreshold",
@@ -54997,10 +54275,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryGatewayErrorsDAA2E45C": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary has been encountering consistent HTTP gateway errors when contacting npmjs servers
for an hour or more. This means the canary has been unable to evaluate SLA compliance for that much time.
@@ -55021,10 +54295,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningFCFBD0E6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/NotRunning",
"ComparisonOperator": "LessThanThreshold",
@@ -55047,10 +54317,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningOrFailing62A8E2F6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmActions": [
"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE",
@@ -55087,8 +54353,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanarySchedule4D94219F": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -55111,8 +54375,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanaryScheduleAllowEventRuleTestConstructHubSourcesNpmJsCanary47220A990ABB5DFD": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -55134,10 +54396,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -55169,10 +54427,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -55226,10 +54480,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Policy",
},
"ConstructHubSourcesNpmJsCanaryStaleCanaryPackageA4C2ACB2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The canary package construct-hub-probe has not published a new version in over 1 day.
This means the SLA alarm is blind — no new versions are being tracked, so SLA breaches cannot be detected.
@@ -55305,25 +54555,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::CloudWatch::Alarm",
},
- "ConstructHubSourcesNpmJsFollowerMissingPackumentsHigh0AB93A32": {
- "Properties": {
- "AlarmDescription": "The npm registry had no packument for an unusually high number of packages announced by
-the CouchDB changes feed. This usually means the registry has an outage or is far behind
-the feed. The packument processor keeps re-checking these packages.
-
-Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
- "AlarmName": "Test/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh",
- "ComparisonOperator": "GreaterThanThreshold",
- "EvaluationPeriods": 1,
- "MetricName": "MissingPackuments",
- "Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
- "Period": 10800,
- "Statistic": "Sum",
- "Threshold": 1500,
- "TreatMissingData": "notBreaching",
- },
- "Type": "AWS::CloudWatch::Alarm",
- },
"ConstructHubSourcesNpmJsFollowerNoChanges2CB08C93": {
"Properties": {
"AlarmDescription": {
@@ -55400,14 +54631,13 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationAfterFollowerUpdateDB1AA774": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJs15A77D2D",
+ "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "Event",
"ServiceToken": {
@@ -55424,14 +54654,12 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesKnownVersions1480B28B",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "RequestResponse",
"ServiceToken": {
@@ -55445,11 +54673,7 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "Custom::Trigger",
"UpdateReplacePolicy": "Delete",
},
- "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7": {
"Metadata": {
"aws:cdk:do-not-refactor": true,
},
@@ -55462,8 +54686,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionEB7112AF": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A",
],
@@ -55475,9 +54697,9 @@ Direct link to Lambda function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "7301756f4001c608471bffd8c435a6d82d1bb8be6f5c44ccba0087649bcf8bc0.zip",
+ "S3Key": "9b619d8252f69c727b70d72add5b64f237cd672709297c7f2c4f0d04abb45002.zip",
},
- "Description": "[Test/ConstructHub/Sources/NpmJs] Copies the known versions from the staging bucket to the known versions table",
+ "Description": "[Test/ConstructHub/Sources/NpmJs/KnownVersionsMigration] Copies the known versions from the staging bucket to the known versions table",
"Environment": {
"Variables": {
"BUCKET_NAME": {
@@ -55505,10 +54727,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -55540,10 +54758,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -55649,8 +54863,8 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Fn::Join": [
"",
[
- "The packument processor function is failing (errors or time-outs). Requests in the
-packument queue use up their attempts while it fails, and may be given up on early.
+ "The packument processor function is failing (errors or time-outs). Requests that keep
+failing it move to the packument dead-letter queue.
Link to the lambda function: /lambda/home#/functions/",
{
@@ -55684,19 +54898,49 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsPackumentProcessorLaggyPackumentLagHigh863AFDFC": {
"Properties": {
- "AlarmDescription": "Laggy packuments take unusually long to catch up: the npm registry serves older revisions
-than the CouchDB changes feed announced, for hours. This usually means the registry has an
-outage or is far behind the feed. The packument processor keeps re-checking these packages.
+ "AlarmDescription": "The npm registry takes unusually long to serve the revisions the CouchDB changes feed
+announced: for hours. This usually means the registry has an outage or is far behind the
+feed. The packument processor keeps re-checking these packages.
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
"AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"ExtendedStatistic": "p90",
- "MetricName": "LaggyPackumentLag",
+ "MetricName": "PackumentDelay",
"Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
"Period": 10800,
- "Threshold": 21600000,
+ "Threshold": 21600,
+ "TreatMissingData": "notBreaching",
+ },
+ "Type": "AWS::CloudWatch::Alarm",
+ },
+ "ConstructHubSourcesNpmJsPackumentProcessorPendingPackumentsHighB797F54C": {
+ "Properties": {
+ "AlarmDescription": "An unusually high number of packages wait for the npm registry to serve the revision the
+CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage
+or is far behind the feed. The packument processor keeps re-checking these packages.
+
+Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
+ "AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh",
+ "ComparisonOperator": "GreaterThanThreshold",
+ "Dimensions": [
+ {
+ "Name": "QueueName",
+ "Value": {
+ "Fn::GetAtt": [
+ "ConstructHubSourcesPackumentProcessorQueue34BDE578",
+ "QueueName",
+ ],
+ },
+ },
+ ],
+ "EvaluationPeriods": 3,
+ "MetricName": "ApproximateNumberOfMessagesNotVisible",
+ "Namespace": "AWS/SQS",
+ "Period": 3600,
+ "Statistic": "Minimum",
+ "Threshold": 2000,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
@@ -55746,10 +54990,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -55781,10 +55021,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -55863,126 +55099,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
],
},
- {
- "Action": [
- "dynamodb:BatchGetItem",
- "dynamodb:Query",
- "dynamodb:GetItem",
- "dynamodb:Scan",
- "dynamodb:ConditionCheckItem",
- "dynamodb:BatchWriteItem",
- "dynamodb:PutItem",
- "dynamodb:UpdateItem",
- "dynamodb:DeleteItem",
- "dynamodb:DescribeTable",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "dynamodb:GetRecords",
- "dynamodb:GetShardIterator",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": "lambda:InvokeFunction",
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- ":*",
- ],
- ],
- },
- ],
- },
{
"Action": [
"sqs:SendMessage",
@@ -56022,7 +55138,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "2e0070c3ad67732b1d20b42f0ebba4cac975f13681fe785dbda2a355319e1c01.zip",
+ "S3Key": "c47e2e7a8f6fed2a7f8614649353767f82be1cb59f9792de8ff448a676948125.zip",
},
"DeadLetterConfig": {
"TargetArn": {
@@ -56353,7 +55469,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Properties": {
"KmsMasterKeyId": "alias/aws/sqs",
"MessageRetentionPeriod": 1209600,
- "VisibilityTimeout": 1800,
},
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
@@ -56362,6 +55477,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
"ConstructHubLicenseListCustomResource323F0FD4",
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesPackumentProcessorFunctionServiceRoleDefaultPolicy4D1F4AD4",
"ConstructHubSourcesPackumentProcessorFunctionServiceRole384F57F3",
],
@@ -56373,7 +55489,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "630d91c0090957d6232d58ca5e9b6b0d55a2ca2b654d8ef37b7f9f20faa9697c.zip",
+ "S3Key": "6b3023d10890a8d4c79a7cb82848d9226f1fbf5196fb7c0deb2d549590bc79da.zip",
},
"Description": "[Test/ConstructHub/Sources/PackumentProcessor] Processes packages from the npm registry, retrying until the registry serves the revision announced by the changes feed",
"Environment": {
@@ -56393,12 +55509,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Ref": "ConstructHubLicenseListBucket9334047F",
},
"LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
- "PACKUMENT_DEAD_LETTER_QUEUE_ARN": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
@@ -56487,22 +55597,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
],
},
},
- {
- "Action": [
- "sqs:ReceiveMessage",
- "sqs:ChangeMessageVisibility",
- "sqs:GetQueueUrl",
- "sqs:DeleteMessage",
- "sqs:GetQueueAttributes",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- },
{
"Action": [
"dynamodb:BatchGetItem",
@@ -56635,28 +55729,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::IAM::Policy",
},
- "ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorDLQEED56E2F4AC5AB3E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
- "Properties": {
- "BatchSize": 10,
- "EventSourceArn": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- "FunctionName": {
- "Ref": "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
- },
- "FunctionResponseTypes": [
- "ReportBatchItemFailures",
- ],
- },
- "Type": "AWS::Lambda::EventSourceMapping",
- },
"ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorQueue026064FBB2863D38": {
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
@@ -56677,7 +55749,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"ReportBatchItemFailures",
],
"ScalingConfig": {
- "MaximumConcurrency": 2,
+ "MaximumConcurrency": 10,
},
},
"Type": "AWS::Lambda::EventSourceMapping",
@@ -56694,7 +55766,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Arn",
],
},
- "maxReceiveCount": 10,
+ "maxReceiveCount": 20,
},
"VisibilityTimeout": 1800,
},
@@ -60375,19 +59447,19 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Received Bytes","expression":"FILL(m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
+ "","metrics":[[{"label":"Received Bytes","expression":"FILL(maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Received Bytes","id":"m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
+ "",{"label":"Received Bytes","id":"maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Transmitted Bytes","id":"md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
+ "",{"label":"Transmitted Bytes","id":"me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Task Count","id":"mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
+ "",{"label":"Task Count","id":"me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
{
"Ref": "AWS::Region",
},
@@ -60497,27 +59569,27 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
@@ -60525,15 +59597,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Change Count","expression":"FILL(mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
+ "","metrics":[[{"label":"Change Count","expression":"FILL(m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
+ "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Late Changes","expression":"FILL(m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5","visible":false,"stat":"Sum"}],[{"label":"Laggy Packuments","expression":"FILL(m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackuments",{"label":"Laggy Packuments","id":"m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc","visible":false,"stat":"Maximum"}],[{"label":"Laggy Packuments Recovered","expression":"FILL(meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentsRecovered",{"label":"Laggy Packuments Recovered","id":"meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentGiveUps",{"label":"Laggy Packument Give-Ups","id":"m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments","expression":"FILL(m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackuments",{"label":"Missing Packuments","id":"m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments Recovered","expression":"FILL(m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentsRecovered",{"label":"Missing Packuments Recovered","id":"m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentGiveUps",{"label":"Missing Packument Give-Ups","id":"m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
+ "","metrics":[[{"label":"Late Changes","expression":"FILL(m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46","visible":false,"stat":"Sum"}],[{"label":"Failed Packument Retrievals","expression":"FILL(ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","FailedPackumentRetrievals",{"label":"Failed Packument Retrievals","id":"ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Laggy",{"label":"Laggy Packument Give-Ups","id":"md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Missing",{"label":"Missing Packument Give-Ups","id":"mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5","visible":false,"stat":"Sum"}],[{"label":"Unreachable Packument Give-Ups","expression":"FILL(m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Unreachable",{"label":"Unreachable Packument Give-Ups","id":"m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -60558,25 +59630,25 @@ def sort_filter_rules(json_obj):
"QueueName",
],
},
- "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentLag",{"label":"Laggy Packument Lag (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
+ "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentDelay",{"label":"Packument Delay (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":2000,"yAxis":"left"},{"color":"#ff0000","label":"Alarm","value":21600,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Seconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Visible Messages","expression":"FILL(m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
+ "","metrics":[[{"label":"Visible Messages","expression":"FILL(mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Visible Messages","id":"m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
+ "",{"label":"Visible Messages","id":"mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Invisible Messages","id":"mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
+ "",{"label":"Invisible Messages","id":"md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
@@ -60622,15 +59694,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -60659,7 +59731,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
+ "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
{
"Ref": "AWS::Region",
},
@@ -60719,15 +59791,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Started","expression":"FILL(m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
+ "","metrics":[[{"label":"Started","expression":"FILL(mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Started","id":"m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
+ "",{"label":"Started","id":"mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Succeeded","id":"md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
+ "",{"label":"Succeeded","id":"m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
@@ -60735,23 +59807,23 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Aborted","expression":"FILL(m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
+ "","metrics":[[{"label":"Aborted","expression":"FILL(mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Aborted","id":"m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
+ "",{"label":"Aborted","id":"mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Failed","id":"m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
+ "",{"label":"Failed","id":"m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Throttled","id":"m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
+ "",{"label":"Throttled","id":"me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Timed Out","id":"m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
+ "",{"label":"Timed Out","id":"m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -60811,7 +59883,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Rules","expression":"FILL(m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
+ "","metrics":[[{"label":"Rules","expression":"FILL(m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubDenyListPruneDeleteQueueBBF60185",
@@ -60822,15 +59894,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
{
"Ref": "ConstructHubPackageDataDC5EF35E",
},
@@ -60854,7 +59926,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with stats","expression":"FILL(m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Packages with stats","expression":"FILL(mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -60878,7 +59950,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -69695,8 +68767,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJs15A77D2D": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22",
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6",
@@ -69709,7 +68779,7 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "a33af01281f9550bce013912ae9360dbe205878277027586445831f1ef0957e6.zip",
+ "S3Key": "82b42c20ce07850910ab4a6d68075fec2f2dd7a6d296a086737a73c4df8329f5.zip",
},
"Description": "[Test/ConstructHub/Sources/NpmJs] Periodically query npmjs.com index for new packages",
"Environment": {
@@ -69718,27 +68788,13 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"BUCKET_NAME": {
"Ref": "ConstructHubSourcesNpmJsStagingBucketB286F0E6",
},
- "DENY_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubDenyListBucket1B3C2C2E",
- },
- "DENY_LIST_OBJECT_KEY": "deny-list.json",
- "FUNCTION_NAME": {
- "Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- },
- "KNOWN_VERSIONS_TABLE_NAME": {
- "Ref": "ConstructHubSourcesKnownVersions1480B28B",
- },
- "LICENSE_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubLicenseListBucket9334047F",
- },
- "LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
},
},
"Handler": "index.handler",
- "MemorySize": 10024,
+ "MemorySize": 2048,
"ReservedConcurrentExecutions": 1,
"Role": {
"Fn::GetAtt": [
@@ -69756,8 +68812,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanary5558FC45": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2",
],
@@ -69809,10 +68863,6 @@ RunBook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsCanaryAlarmBE2B479E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "New versions of construct-hub-probe have been published over 5 minutes ago and are still not visible in construct hub
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
@@ -69856,10 +68906,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryFailingE338711F": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/Failing",
"ComparisonOperator": "GreaterThanThreshold",
@@ -69882,10 +68928,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryGatewayErrorsDAA2E45C": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary has been encountering consistent HTTP gateway errors when contacting npmjs servers
for an hour or more. This means the canary has been unable to evaluate SLA compliance for that much time.
@@ -69906,10 +68948,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningFCFBD0E6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "Test/ConstructHub/Sources/NpmJs/Canary/NotRunning",
"ComparisonOperator": "LessThanThreshold",
@@ -69932,10 +68970,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningOrFailing62A8E2F6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmActions": [
"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE",
@@ -69972,8 +69006,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanarySchedule4D94219F": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -69996,8 +69028,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanaryScheduleAllowEventRuleTestConstructHubSourcesNpmJsCanary47220A990ABB5DFD": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -70019,10 +69049,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -70054,10 +69080,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -70111,10 +69133,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Policy",
},
"ConstructHubSourcesNpmJsCanaryStaleCanaryPackageA4C2ACB2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The canary package construct-hub-probe has not published a new version in over 1 day.
This means the SLA alarm is blind — no new versions are being tracked, so SLA breaches cannot be detected.
@@ -70190,25 +69208,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::CloudWatch::Alarm",
},
- "ConstructHubSourcesNpmJsFollowerMissingPackumentsHigh0AB93A32": {
- "Properties": {
- "AlarmDescription": "The npm registry had no packument for an unusually high number of packages announced by
-the CouchDB changes feed. This usually means the registry has an outage or is far behind
-the feed. The packument processor keeps re-checking these packages.
-
-Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
- "AlarmName": "Test/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh",
- "ComparisonOperator": "GreaterThanThreshold",
- "EvaluationPeriods": 1,
- "MetricName": "MissingPackuments",
- "Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
- "Period": 10800,
- "Statistic": "Sum",
- "Threshold": 1500,
- "TreatMissingData": "notBreaching",
- },
- "Type": "AWS::CloudWatch::Alarm",
- },
"ConstructHubSourcesNpmJsFollowerNoChanges2CB08C93": {
"Properties": {
"AlarmDescription": {
@@ -70285,14 +69284,13 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationAfterFollowerUpdateDB1AA774": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJs15A77D2D",
+ "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "Event",
"ServiceToken": {
@@ -70309,14 +69307,12 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesKnownVersions1480B28B",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7",
},
"InvocationType": "RequestResponse",
"ServiceToken": {
@@ -70330,11 +69326,7 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "Custom::Trigger",
"UpdateReplacePolicy": "Delete",
},
- "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701942e6854adcead20938048c1943418fe": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A70106b8ef57d61b939fad0eb7c4869e2ae7": {
"Metadata": {
"aws:cdk:do-not-refactor": true,
},
@@ -70347,8 +69339,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionEB7112AF": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A",
],
@@ -70360,9 +69350,9 @@ Direct link to Lambda function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "7301756f4001c608471bffd8c435a6d82d1bb8be6f5c44ccba0087649bcf8bc0.zip",
+ "S3Key": "9b619d8252f69c727b70d72add5b64f237cd672709297c7f2c4f0d04abb45002.zip",
},
- "Description": "[Test/ConstructHub/Sources/NpmJs] Copies the known versions from the staging bucket to the known versions table",
+ "Description": "[Test/ConstructHub/Sources/NpmJs/KnownVersionsMigration] Copies the known versions from the staging bucket to the known versions table",
"Environment": {
"Variables": {
"BUCKET_NAME": {
@@ -70390,10 +69380,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -70425,10 +69411,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -70534,8 +69516,8 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Fn::Join": [
"",
[
- "The packument processor function is failing (errors or time-outs). Requests in the
-packument queue use up their attempts while it fails, and may be given up on early.
+ "The packument processor function is failing (errors or time-outs). Requests that keep
+failing it move to the packument dead-letter queue.
Link to the lambda function: /lambda/home#/functions/",
{
@@ -70569,19 +69551,49 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsPackumentProcessorLaggyPackumentLagHigh863AFDFC": {
"Properties": {
- "AlarmDescription": "Laggy packuments take unusually long to catch up: the npm registry serves older revisions
-than the CouchDB changes feed announced, for hours. This usually means the registry has an
-outage or is far behind the feed. The packument processor keeps re-checking these packages.
+ "AlarmDescription": "The npm registry takes unusually long to serve the revisions the CouchDB changes feed
+announced: for hours. This usually means the registry has an outage or is far behind the
+feed. The packument processor keeps re-checking these packages.
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
"AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"ExtendedStatistic": "p90",
- "MetricName": "LaggyPackumentLag",
+ "MetricName": "PackumentDelay",
"Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
"Period": 10800,
- "Threshold": 21600000,
+ "Threshold": 21600,
+ "TreatMissingData": "notBreaching",
+ },
+ "Type": "AWS::CloudWatch::Alarm",
+ },
+ "ConstructHubSourcesNpmJsPackumentProcessorPendingPackumentsHighB797F54C": {
+ "Properties": {
+ "AlarmDescription": "An unusually high number of packages wait for the npm registry to serve the revision the
+CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage
+or is far behind the feed. The packument processor keeps re-checking these packages.
+
+Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
+ "AlarmName": "Test/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh",
+ "ComparisonOperator": "GreaterThanThreshold",
+ "Dimensions": [
+ {
+ "Name": "QueueName",
+ "Value": {
+ "Fn::GetAtt": [
+ "ConstructHubSourcesPackumentProcessorQueue34BDE578",
+ "QueueName",
+ ],
+ },
+ },
+ ],
+ "EvaluationPeriods": 3,
+ "MetricName": "ApproximateNumberOfMessagesNotVisible",
+ "Namespace": "AWS/SQS",
+ "Period": 3600,
+ "Statistic": "Minimum",
+ "Threshold": 2000,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
@@ -70631,10 +69643,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -70666,10 +69674,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -70748,126 +69752,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
],
},
- {
- "Action": [
- "dynamodb:BatchGetItem",
- "dynamodb:Query",
- "dynamodb:GetItem",
- "dynamodb:Scan",
- "dynamodb:ConditionCheckItem",
- "dynamodb:BatchWriteItem",
- "dynamodb:PutItem",
- "dynamodb:UpdateItem",
- "dynamodb:DeleteItem",
- "dynamodb:DescribeTable",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "dynamodb:GetRecords",
- "dynamodb:GetShardIterator",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": "lambda:InvokeFunction",
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- ":*",
- ],
- ],
- },
- ],
- },
{
"Action": [
"sqs:SendMessage",
@@ -70907,7 +69791,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "2e0070c3ad67732b1d20b42f0ebba4cac975f13681fe785dbda2a355319e1c01.zip",
+ "S3Key": "c47e2e7a8f6fed2a7f8614649353767f82be1cb59f9792de8ff448a676948125.zip",
},
"DeadLetterConfig": {
"TargetArn": {
@@ -71238,7 +70122,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Properties": {
"KmsMasterKeyId": "alias/aws/sqs",
"MessageRetentionPeriod": 1209600,
- "VisibilityTimeout": 1800,
},
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
@@ -71247,6 +70130,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
"ConstructHubLicenseListCustomResource323F0FD4",
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesPackumentProcessorFunctionServiceRoleDefaultPolicy4D1F4AD4",
"ConstructHubSourcesPackumentProcessorFunctionServiceRole384F57F3",
],
@@ -71258,7 +70142,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "630d91c0090957d6232d58ca5e9b6b0d55a2ca2b654d8ef37b7f9f20faa9697c.zip",
+ "S3Key": "6b3023d10890a8d4c79a7cb82848d9226f1fbf5196fb7c0deb2d549590bc79da.zip",
},
"Description": "[Test/ConstructHub/Sources/PackumentProcessor] Processes packages from the npm registry, retrying until the registry serves the revision announced by the changes feed",
"Environment": {
@@ -71278,12 +70162,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Ref": "ConstructHubLicenseListBucket9334047F",
},
"LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
- "PACKUMENT_DEAD_LETTER_QUEUE_ARN": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
@@ -71372,22 +70250,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
],
},
},
- {
- "Action": [
- "sqs:ReceiveMessage",
- "sqs:ChangeMessageVisibility",
- "sqs:GetQueueUrl",
- "sqs:DeleteMessage",
- "sqs:GetQueueAttributes",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- },
{
"Action": [
"dynamodb:BatchGetItem",
@@ -71520,28 +70382,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::IAM::Policy",
},
- "ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorDLQEED56E2F4AC5AB3E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
- "Properties": {
- "BatchSize": 10,
- "EventSourceArn": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- "FunctionName": {
- "Ref": "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
- },
- "FunctionResponseTypes": [
- "ReportBatchItemFailures",
- ],
- },
- "Type": "AWS::Lambda::EventSourceMapping",
- },
"ConstructHubSourcesPackumentProcessorFunctionSqsEventSourceTestConstructHubSourcesPackumentProcessorQueue026064FBB2863D38": {
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
@@ -71562,7 +70402,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"ReportBatchItemFailures",
],
"ScalingConfig": {
- "MaximumConcurrency": 2,
+ "MaximumConcurrency": 10,
},
},
"Type": "AWS::Lambda::EventSourceMapping",
@@ -71579,7 +70419,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Arn",
],
},
- "maxReceiveCount": 10,
+ "maxReceiveCount": 20,
},
"VisibilityTimeout": 1800,
},
diff --git a/src/__tests__/devapp/__snapshots__/snapshot.test.ts.snap b/src/__tests__/devapp/__snapshots__/snapshot.test.ts.snap
index 5eb792077..ba28d8ff2 100644
--- a/src/__tests__/devapp/__snapshots__/snapshot.test.ts.snap
+++ b/src/__tests__/devapp/__snapshots__/snapshot.test.ts.snap
@@ -574,19 +574,19 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Received Bytes","expression":"FILL(m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
+ "","metrics":[[{"label":"Received Bytes","expression":"FILL(maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d, 0)"}],["ECS/ContainerInsights","NetworkRxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Received Bytes","id":"m67cc14db3275d4a2af71847df2ebb376a00b015f62c4ff9d1aedb9bc615a6cf0","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
+ "",{"label":"Received Bytes","id":"maac4fc67891a4d36db477c02a39018d3c329c1296c45bb9d1c2ce178c8f66a5d","visible":false,"stat":"Maximum"}],[{"label":"Transmitted Bytes","expression":"FILL(me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c, 0)"}],["ECS/ContainerInsights","NetworkTxBytes","ClusterName","",
{
"Ref": "ConstructHubOrchestrationCluster3D6F0081",
},
- "",{"label":"Transmitted Bytes","id":"md6781afc8bf73de5587d36039d8226d1c0fe0b50a1c949759d3d8d8cd2e3f6d1","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
+ "",{"label":"Transmitted Bytes","id":"me4880e4edfe4520fcdfbbca135be44da41b55170ec239268283002f6a05a2f6c","visible":false,"stat":"Maximum"}],[{"label":"Task Count","expression":"FILL(me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b, 0)","yAxis":"right"}],["ECS/ContainerInsights","TaskCount","ExecutionMetrics","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Task Count","id":"mbb258976f5c025a7dff5289417a6b07619e000e4af1a427fecc57b31586fd6dd","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
+ "",{"label":"Task Count","id":"me0c6f5060fc9819a4d894ef9daa2bac27ac75f65892793ff5fc50193032b461b","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0},"right":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":0,"y":16,"properties":{"view":"timeSeries","title":"ECS Task Monitor","region":"",
{
"Ref": "AWS::Region",
},
@@ -696,27 +696,27 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJs15A77D2D",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","RemainingTime",{"label":"Remaining Time","stat":"Minimum","yAxis":"right"}]],"yAxis":{"left":{"min":0},"right":{"min":0}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":59,"properties":{"view":"timeSeries","title":"Stager Health","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}],["AWS/Lambda","Duration","FunctionName","",
{
"Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
},
@@ -724,15 +724,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Change Count","expression":"FILL(mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"mf6a938229aec623f5cf21e3ae3401901e7f7c6ebd5774ab6ac6e74af83efd121","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m5b235d813bd8ded65d7de9a1345c9b49a8cf2af40e7e98ddbb8cb73e00783a8a","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"m4d6c513faac55be4bca785e8587a9a145b65f5fe675318c9c5c52f3ada197b7b","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mec485aa83505431ed7a356970082cd4815c310504ff176dd3eeb241ae7bbf0c4","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
+ "","metrics":[[{"label":"Change Count","expression":"FILL(m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","ChangeCount",{"label":"Change Count","id":"m76193c7211f3b7a7c8eed81b785e74c5ca3c32bcb9945d27a1798097d291ec01","visible":false,"stat":"Sum"}],[{"label":"Unprocessable","expression":"FILL(m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","UnprocessableEntity",{"label":"Unprocessable","id":"m42282307fa51675e1c2d1e1f3101965b973b1c0abdaf25d9c53a7f93ed3f2268","visible":false,"stat":"Sum"}],[{"label":"Lag to npmjs.com","expression":"FILL(mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","NpmJsChangeAge",{"label":"Lag to npmjs.com","id":"mfbb6e41e7da0626959153675c4f4d637b819cb638721e3159bb8b1b4e3e6c512","visible":false,"stat":"Minimum"}],[{"label":"Package Version Age","expression":"FILL(mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3, REPEAT)","yAxis":"right"}],["ConstructHub/PackageSource/NpmJs/Follower","PackageVersionAge",{"label":"Package Version Age","id":"mf711b5141e6d51baee729ac35cf6d7a1bf6e8f8e12dd410be43c9a02d92421a3","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":65,"properties":{"view":"timeSeries","title":"CouchDB Changes","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mcc89a801dd7db60ea52e74b9851bd34a3899e7a26323ac98feb632cdf70c2500","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
+ "","metrics":[[{"label":"Last Sequence Number","expression":"FILL(mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d, REPEAT)"}],["ConstructHub/PackageSource/NpmJs/Follower","LastSeq",{"label":"Last Sequence Number","id":"mf662012bb5ce41eaa88e1e452c34400864b1c7ac9d8ea0ec8f40cc2ca26e407d","visible":false,"stat":"Maximum"}]],"yAxis":{},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":71,"properties":{"view":"timeSeries","title":"Feed Reliability","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Late Changes","expression":"FILL(m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m97b26d9c3912f8122fc8cbc26c10d7e362f10a1b01dd7b6fc615793a0614ffd5","visible":false,"stat":"Sum"}],[{"label":"Laggy Packuments","expression":"FILL(m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackuments",{"label":"Laggy Packuments","id":"m7542c42c2a42804f45673f1b7a1e208ef9657546e83a7fed66558c0c9a9458fc","visible":false,"stat":"Maximum"}],[{"label":"Laggy Packuments Recovered","expression":"FILL(meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentsRecovered",{"label":"Laggy Packuments Recovered","id":"meebc873175632650e3dbd407c0e22f4395c7b945fffbd66f17cc225c7f3c5ab7","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentGiveUps",{"label":"Laggy Packument Give-Ups","id":"m25c8aa905abbcebe79405fb8d308d3b26cc11789e67b7b432396024cc3688665","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments","expression":"FILL(m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackuments",{"label":"Missing Packuments","id":"m01772d2035c66bb758d8af88685f9a5f508aac1982cd26d7b1ed107a5e948e62","visible":false,"stat":"Sum"}],[{"label":"Missing Packuments Recovered","expression":"FILL(m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentsRecovered",{"label":"Missing Packuments Recovered","id":"m65c59efca9f729008affb3924f59d4dc66e24297ee63442794b259b64a2a85e7","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MissingPackumentGiveUps",{"label":"Missing Packument Give-Ups","id":"m853f955d255e0171792576a2bb4142132ad90c73ede7d119e6bdd8c383111e72","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"mb4ba2ab8081f9474c7f13c3726c05a8d8243b0432c76e4ce05db82f5f80bf5bb","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
+ "","metrics":[[{"label":"Late Changes","expression":"FILL(m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeCount",{"label":"Late Changes","id":"m5d7d5b429d9cb8fffd49a0bf92d717f7ba58c308fbc44918776de812553fff46","visible":false,"stat":"Sum"}],[{"label":"Failed Packument Retrievals","expression":"FILL(ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","FailedPackumentRetrievals",{"label":"Failed Packument Retrievals","id":"ma1b3dac6ef279b2a2f2dcd72ccc33441c2d6f0643b73ac18fe9c3c781cc7921b","visible":false,"stat":"Sum"}],[{"label":"Laggy Packument Give-Ups","expression":"FILL(md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Laggy",{"label":"Laggy Packument Give-Ups","id":"md56333206a0a5f2ad191f6aadf588f19afe7869f9db160cd053be545669751fc","visible":false,"stat":"Sum"}],[{"label":"Missing Packument Give-Ups","expression":"FILL(mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Missing",{"label":"Missing Packument Give-Ups","id":"mc8bfbcf427f45274605721e7cb3b10c34aaaf25760446cf24cb85a7b6b5e46f5","visible":false,"stat":"Sum"}],[{"label":"Unreachable Packument Give-Ups","expression":"FILL(m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentGiveUps","Reason","Unreachable",{"label":"Unreachable Packument Give-Ups","id":"m278aaaac85bc5c62f6ae103b5e609d25986f67fe9ac2c7a4606dc4715fad6454","visible":false,"stat":"Sum"}],[{"label":"Metadata Fetch Failures","expression":"FILL(m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3, 0)"}],["ConstructHub/PackageSource/NpmJs/Follower","MetadataFetchFailures",{"label":"Metadata Fetch Failures","id":"m5b81e0403a27feed026507e11f4340b823a62957fabb3145e3c943eb26f4dcf3","visible":false,"stat":"Sum"}],["ConstructHub/PackageSource/NpmJs/Follower","LateChangeLag",{"label":"Late Change Lag (max)","stat":"Maximum","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Scan Window","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":12,"y":71,"properties":{"view":"timeSeries","title":"Packument Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -757,25 +757,25 @@ def sort_filter_rules(json_obj):
"QueueName",
],
},
- "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","LaggyPackumentLag",{"label":"Laggy Packument Lag (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":21600000,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Milliseconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
+ "",{"label":"Delayed","stat":"Maximum"}],["ConstructHub/PackageSource/NpmJs/Follower","PackumentDelay",{"label":"Packument Delay (p90)","stat":"p90","yAxis":"right"}]],"annotations":{"horizontal":[{"color":"#ff0000","label":"Alarm","value":2000,"yAxis":"left"},{"color":"#ff0000","label":"Alarm","value":21600,"yAxis":"right"}]},"yAxis":{"left":{"min":0},"right":{"label":"Seconds","min":0,"showUnits":false}},"period":300}},{"type":"metric","width":12,"height":6,"x":0,"y":77,"properties":{"view":"timeSeries","title":"Stager Dead-Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Visible Messages","expression":"FILL(m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
+ "","metrics":[[{"label":"Visible Messages","expression":"FILL(mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Visible Messages","id":"m96c7bb4160011a049b6b07c0feab8fb02e5a8d4aa466939592829f864dde6400","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
+ "",{"label":"Visible Messages","id":"mbe1485349a6d634e264deba20d45cd6b1a7720cb1571be5bcad21160d1619f02","visible":false,"stat":"Maximum"}],[{"label":"Invisible Messages","expression":"FILL(md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae, 0)"}],["AWS/SQS","ApproximateNumberOfMessagesNotVisible","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
"QueueName",
],
},
- "",{"label":"Invisible Messages","id":"mf74066283a392fc98a0cd7a405f2aa9b5af544d3a87542f06fff7fd069fd8578","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
+ "",{"label":"Invisible Messages","id":"md202ace0e6d5791f805d2d5f8ff768252b669fda1ac398e128ec2c159f3424ae","visible":false,"stat":"Maximum"}],["AWS/SQS","ApproximateAgeOfOldestMessage","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubSourcesStagerDLQ80BD2600",
@@ -821,15 +821,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubIngestion407909CE",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":60}},{"type":"metric","width":12,"height":6,"x":12,"y":91,"properties":{"view":"timeSeries","title":"Input Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -858,7 +858,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"m0c5f10aa73687a21aa44b8985d19311246bca6c2cd1b2256b9f3e78c71e94fa3","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m3a39d9b0bf974255f27dc95e44c8574bdfce2b97e49a7504346a77c5c9f6a3e1","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"me19ae9c3f20ae715e3462f9402684a3817282218f36e69494a60bc251e3435a6","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m7c1d407f17f8d2452a0bf87ac06fdd032de385a2758254f4192d6e17ed40d44b","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m7084dfec3c5bab86694d7ae438460f471c174a94bc67c9c9738e3ab60246b661","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
+ "","stacked":true,"metrics":[[{"label":"Invalid Assemblies","expression":"FILL(mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf, 0)"}],["ConstructHub/Ingestion","InvalidAssembly",{"label":"Invalid Assemblies","id":"mec9714175791cdffbfeeff9185ee309211fec45815ec54b0ceffb9915ccfeccf","visible":false,"stat":"Sum"}],[{"label":"Invalid Tarball","expression":"FILL(m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85, 0)"}],["ConstructHub/Ingestion","InvalidTarball",{"label":"Invalid Tarball","id":"m6c4780740957a4f8ec8301e9b9fd4825c9120a41bddff0f79d50969c09d2eb85","visible":false,"stat":"Sum"}],[{"label":"Ineligible License","expression":"FILL(ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9, 0)"}],["ConstructHub/Ingestion","IneligibleLicense",{"label":"Ineligible License","id":"ma928e15c7bb6743f014ac10efbd821d90c22398f29840a77d5283201a1a0d1f9","visible":false,"stat":"Sum"}],[{"label":"Mismatched Identity","expression":"FILL(m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807, 0)"}],["ConstructHub/Ingestion","MismatchedIdentityRejections",{"label":"Mismatched Identity","id":"m860ba6d187ecc8e70a19db1a25a47c57a9e4cac844b9800a4553d680d92af807","visible":false,"stat":"Sum"}],[{"label":"Found License file","expression":"FILL(m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85, 0)"}],["ConstructHub/Ingestion","FoundLicenseFile",{"label":"Found License file","id":"m3e0ffa0473bcc0c076842c24f174f320c5b80549f0d2807863978c5a85725d85","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"label":"Count","min":0,"showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":12,"y":97,"properties":{"view":"timeSeries","title":"Dead Letters","region":"",
{
"Ref": "AWS::Region",
},
@@ -918,15 +918,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Started","expression":"FILL(m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
+ "","metrics":[[{"label":"Started","expression":"FILL(mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8, 0)"}],["AWS/States","ExecutionsStarted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Started","id":"m392141ff4cfa3bbe1889b2db42bcf20599513e199a0b9fb8dc736cde893c1d7c","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
+ "",{"label":"Started","id":"mf92be3ee81a541ec69a1e6734030385ffc3f50bb896a26386125e26f1c3251d8","visible":false,"stat":"Sum"}],[{"label":"Succeeded","expression":"FILL(m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244, 0)"}],["AWS/States","ExecutionsSucceeded","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Succeeded","id":"md1b80634be6e2f057c84f44fab13979a6445395ea2dc357cd12d0ba9f504e6d1","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
+ "",{"label":"Succeeded","id":"m9295dcb0dd88129fe01ab04ddae381625eae9f21990511f4e7b5c48e3e880244","visible":false,"stat":"Sum"}],["AWS/States","ExecutionTime","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
@@ -934,23 +934,23 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Aborted","expression":"FILL(m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
+ "","metrics":[[{"label":"Aborted","expression":"FILL(mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe, 0)"}],["AWS/States","ExecutionsAborted","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Aborted","id":"m7c13255adf2b6d90baaa9e4e952e72ce260730c93b662336d01e3342f6255e08","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
+ "",{"label":"Aborted","id":"mf087cf7fbbc664f9e667ca1d85cfb85ff1c6fb5881ed388419e45754b1a773fe","visible":false,"stat":"Sum"}],[{"label":"Failed","expression":"FILL(m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709, 0)"}],["AWS/States","ExecutionsFailed","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Failed","id":"m503cb5a7568675222eb2ac827982f88ad300c986505dabfafe1707080946e597","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
+ "",{"label":"Failed","id":"m70948d89c399c9fc76776f39c49935f56329bc551ebfb46bb1a2a06a60b19709","visible":false,"stat":"Sum"}],[{"label":"Throttled","expression":"FILL(me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a, 0)"}],["AWS/States","ExecutionThrottled","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Throttled","id":"m278670a6ffa3ce32fec8fcb73c1cfdc4c965389617e2387ab5852ebb00b2a81f","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
+ "",{"label":"Throttled","id":"me88984e2341e3fb247b09980bee94da0ad912c94c66f0489ac3e83dabe9b2e0a","visible":false,"stat":"Sum"}],[{"label":"Timed Out","expression":"FILL(m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d, 0)"}],["AWS/States","ExecutionsTimedOut","StateMachineArn","",
{
"Ref": "ConstructHubOrchestration39161A46",
},
- "",{"label":"Timed Out","id":"m106d91118c893ec9037d16448722184f1ebdcca08a617e1f13758151a8c85a21","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
+ "",{"label":"Timed Out","id":"m2480327d19e2e66c474c6eeddec30639bb09604b2acad8e1d9d315e2b7a3398d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0,"label":"Count","showUnits":false}}}},{"type":"metric","width":12,"height":6,"x":0,"y":111,"properties":{"view":"timeSeries","title":"Dead Letter Queue","region":"",
{
"Ref": "AWS::Region",
},
@@ -1010,7 +1010,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Rules","expression":"FILL(m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m41327b0edbbef1ca627d9503d1b9b9fab401700118519537b58e0557adee7e4f","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
+ "","metrics":[[{"label":"Rules","expression":"FILL(m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3, REPEAT)"}],["ConstructHub/DenyList","DenyListRuleCount",{"label":"Rules","id":"m8dcebecfeee53a2b76f5cd59fc8daec56fc6ffae6c1c3fe4bb8f1e8b3995c5f3","visible":false,"stat":"Maximum"}],["AWS/SQS","NumberOfMessagesDeleted","QueueName","",
{
"Fn::GetAtt": [
"ConstructHubDenyListPruneDeleteQueueBBF60185",
@@ -1021,15 +1021,15 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Invocations","expression":"FILL(m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
+ "","metrics":[[{"label":"Invocations","expression":"FILL(mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f, 0)"}],["AWS/Lambda","Invocations","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Invocations","id":"m9ff955bd33652ecefb4dd9402064988aa5e418fcf59360156ff8c9e38dbde5e2","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55, 0)"}],["AWS/Lambda","Errors","FunctionName","",
+ "",{"label":"Invocations","id":"mbb6e9076c31adf6f3e9e78a6d00733dec47b99d2a05b742f14ad10e368f1998f","visible":false,"stat":"Sum"}],[{"label":"Errors","expression":"FILL(m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424, 0)"}],["AWS/Lambda","Errors","FunctionName","",
{
"Ref": "ConstructHubDenyListPrunePruneHandler30B33551",
},
- "",{"label":"Errors","id":"m3aa18789f406dc22d5fd69d6a8b1ae08cbc04aabfde21bee51e16796b37a2e55","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
+ "",{"label":"Errors","id":"m8ba134f4dff09a471c0411dd4dc76a6ab0c7c0ee4abaec9732ca2f7cb2603424","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}},"period":300}},{"type":"text","width":24,"height":2,"x":0,"y":125,"properties":{"markdown":"# Package Stats\\n\\n[button:primary:Package Stats Object](/s3/object/",
{
"Ref": "ConstructHubPackageDataDC5EF35E",
},
@@ -1053,7 +1053,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with stats","expression":"FILL(m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"m47411943a6e8f8e16a1dd905ff43cab11425b802c4d32615e081cab30c15f29f","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Packages with stats","expression":"FILL(mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0, REPEAT)"}],["ConstructHub/PackageStats","RegisteredPackagesWithStats",{"label":"Packages with stats","id":"mce57b51ae42406eedfb298879731c4b7856818ed6b66a982103a3262a30827c0","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":127,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -1077,7 +1077,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m343ebb2e5802fe223e549d8262d8d0c364846e0276426bc0a2d872e83bd8e63d","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
+ "","metrics":[[{"label":"Package versions recorded","expression":"FILL(m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8, REPEAT)"}],["ConstructHub/VersionTracker","TrackedVersionsCount",{"label":"Package versions recorded","id":"m6ef14e073818d5b67e304a3dca842b3da0a6c2400e6353f152fa142056dcebf8","visible":false,"stat":"Maximum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":135,"properties":{"view":"timeSeries","title":"Invocation Duration","region":"",
{
"Ref": "AWS::Region",
},
@@ -1150,7 +1150,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Packages with release notes","expression":"FILL(m7a7a3037972a088d52187e29766f681a9cb9642d00a12e818823d134184ff48d, REPEAT)"}],["ConstructHub/ReleaseNotes","PackageWithChangeLog",{"label":"Packages with release notes","id":"m7a7a3037972a088d52187e29766f681a9cb9642d00a12e818823d134184ff48d","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":143,"properties":{"view":"timeSeries","title":"Release notes generation Errors","region":"",
+ "","metrics":[[{"label":"Packages with release notes","expression":"FILL(m7fc8d3ac8577404b84d391ef896a25d01da827ec9da2fe90db320cf92c6522ae, REPEAT)"}],["ConstructHub/ReleaseNotes","PackageWithChangeLog",{"label":"Packages with release notes","id":"m7fc8d3ac8577404b84d391ef896a25d01da827ec9da2fe90db320cf92c6522ae","visible":false,"stat":"Sum"}]],"yAxis":{"left":{"min":0}}}},{"type":"metric","width":12,"height":6,"x":12,"y":143,"properties":{"view":"timeSeries","title":"Release notes generation Errors","region":"",
{
"Ref": "AWS::Region",
},
@@ -1158,7 +1158,7 @@ def sort_filter_rules(json_obj):
{
"Ref": "AWS::Region",
},
- "","metrics":[[{"label":"Limit","expression":"FILL(mcf810098fa7b0359cfa64484e165026013fa6611de36e48a68984a9615f7599d, REPEAT)"}],["ConstructHub/ReleaseNotes","GhLimitsLimit",{"label":"Limit","id":"mcf810098fa7b0359cfa64484e165026013fa6611de36e48a68984a9615f7599d","visible":false,"stat":"Maximum"}],[{"label":"Used","expression":"FILL(mc54991399581cec857a3c1773e2649cbfb65cef7ea4e459f2ada3ee31c60782e, REPEAT)"}],["ConstructHub/ReleaseNotes","GhLimitsUsed",{"label":"Used","id":"mc54991399581cec857a3c1773e2649cbfb65cef7ea4e459f2ada3ee31c60782e","visible":false,"stat":"Maximum"}],[{"label":"Remaining","expression":"FILL(m3c4202dbd25b40c6524935352f9d34858b3374ed5079dbd6aea164767195d54a, REPEAT)"}],["ConstructHub/ReleaseNotes","GhRateLimitsRemaining",{"label":"Remaining","id":"m3c4202dbd25b40c6524935352f9d34858b3374ed5079dbd6aea164767195d54a","visible":false,"stat":"Minimum"}]],"yAxis":{}}}]}",
+ "","metrics":[[{"label":"Limit","expression":"FILL(m5158e7aa201a0aa1d983f46e56fd17a9f661b2dea67c77ed0b0f9ef5f197d9ef, REPEAT)"}],["ConstructHub/ReleaseNotes","GhLimitsLimit",{"label":"Limit","id":"m5158e7aa201a0aa1d983f46e56fd17a9f661b2dea67c77ed0b0f9ef5f197d9ef","visible":false,"stat":"Maximum"}],[{"label":"Used","expression":"FILL(m94009ce17351487c796348d1ad6c8424128dafd07a1cec8d6580130f8a573e14, REPEAT)"}],["ConstructHub/ReleaseNotes","GhLimitsUsed",{"label":"Used","id":"m94009ce17351487c796348d1ad6c8424128dafd07a1cec8d6580130f8a573e14","visible":false,"stat":"Maximum"}],[{"label":"Remaining","expression":"FILL(ma11f332c98edab9054557c34b21a573f3248d7e74ee980146429a2d1b0e12370, REPEAT)"}],["ConstructHub/ReleaseNotes","GhRateLimitsRemaining",{"label":"Remaining","id":"ma11f332c98edab9054557c34b21a573f3248d7e74ee980146429a2d1b0e12370","visible":false,"stat":"Minimum"}]],"yAxis":{}}}]}",
],
],
},
@@ -11292,8 +11292,6 @@ Direct link to the function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJs15A77D2D": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22",
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6",
@@ -11306,7 +11304,7 @@ Direct link to the function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "a33af01281f9550bce013912ae9360dbe205878277027586445831f1ef0957e6.zip",
+ "S3Key": "82b42c20ce07850910ab4a6d68075fec2f2dd7a6d296a086737a73c4df8329f5.zip",
},
"Description": "[dev/ConstructHub/Sources/NpmJs] Periodically query npmjs.com index for new packages",
"Environment": {
@@ -11315,27 +11313,13 @@ Direct link to the function: /lambda/home#/functions/",
"BUCKET_NAME": {
"Ref": "ConstructHubSourcesNpmJsStagingBucketB286F0E6",
},
- "DENY_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubDenyListBucket1B3C2C2E",
- },
- "DENY_LIST_OBJECT_KEY": "deny-list.json",
- "FUNCTION_NAME": {
- "Ref": "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- },
- "KNOWN_VERSIONS_TABLE_NAME": {
- "Ref": "ConstructHubSourcesKnownVersions1480B28B",
- },
- "LICENSE_LIST_BUCKET_NAME": {
- "Ref": "ConstructHubLicenseListBucket9334047F",
- },
- "LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
},
},
"Handler": "index.handler",
- "MemorySize": 10024,
+ "MemorySize": 2048,
"ReservedConcurrentExecutions": 1,
"Role": {
"Fn::GetAtt": [
@@ -11353,8 +11337,6 @@ Direct link to the function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsCanary5558FC45": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2",
],
@@ -11406,10 +11388,6 @@ Direct link to the function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsCanaryAlarmBE2B479E": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "New versions of construct-hub-probe have been published over 5 minutes ago and are still not visible in construct hub
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
@@ -11453,10 +11431,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryFailingE338711F": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "dev/ConstructHub/Sources/NpmJs/Canary/Failing",
"ComparisonOperator": "GreaterThanThreshold",
@@ -11479,10 +11453,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryGatewayErrorsDAA2E45C": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary has been encountering consistent HTTP gateway errors when contacting npmjs servers
for an hour or more. This means the canary has been unable to evaluate SLA compliance for that much time.
@@ -11503,10 +11473,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningFCFBD0E6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmName": "dev/ConstructHub/Sources/NpmJs/Canary/NotRunning",
"ComparisonOperator": "LessThanThreshold",
@@ -11529,10 +11495,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::CloudWatch::Alarm",
},
"ConstructHubSourcesNpmJsCanaryNotRunningOrFailing62A8E2F6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The NpmJs package canary is not running or is failing. This prevents alarming when this instance of
ConstructHub falls out of SLA for new package ingestion!
@@ -11566,8 +11528,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanarySchedule4D94219F": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -11590,8 +11550,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsCanaryScheduleAllowEventRuledevConstructHubSourcesNpmJsCanaryC48E9D5AD1BB0C82": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B",
],
"Properties": {
@@ -11613,10 +11571,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleC4CBCDA2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -11648,10 +11602,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsCanaryServiceRoleDefaultPolicy630F813B": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -11705,10 +11655,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Policy",
},
"ConstructHubSourcesNpmJsCanaryStaleCanaryPackageA4C2ACB2": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AlarmDescription": "The canary package construct-hub-probe has not published a new version in over 1 day.
This means the SLA alarm is blind — no new versions are being tracked, so SLA breaches cannot be detected.
@@ -11784,25 +11730,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::CloudWatch::Alarm",
},
- "ConstructHubSourcesNpmJsFollowerMissingPackumentsHigh0AB93A32": {
- "Properties": {
- "AlarmDescription": "The npm registry had no packument for an unusually high number of packages announced by
-the CouchDB changes feed. This usually means the registry has an outage or is far behind
-the feed. The packument processor keeps re-checking these packages.
-
-Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
- "AlarmName": "dev/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh",
- "ComparisonOperator": "GreaterThanThreshold",
- "EvaluationPeriods": 1,
- "MetricName": "MissingPackuments",
- "Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
- "Period": 10800,
- "Statistic": "Sum",
- "Threshold": 1500,
- "TreatMissingData": "notBreaching",
- },
- "Type": "AWS::CloudWatch::Alarm",
- },
"ConstructHubSourcesNpmJsFollowerNoChanges2CB08C93": {
"Properties": {
"AlarmDescription": {
@@ -11876,14 +11803,13 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationAfterFollowerUpdateDB1AA774": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJs15A77D2D",
+ "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A7011c612be80bca7973713bb9924f79b406",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701f6dda04ffcec81d842b5ccc65a7d6f5f",
},
"InvocationType": "Event",
"ServiceToken": {
@@ -11900,14 +11826,12 @@ Direct link to Lambda function: /lambda/home#/functions/",
"ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619": {
"DeletionPolicy": "Delete",
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesKnownVersions1480B28B",
],
"Properties": {
"ExecuteOnHandlerChange": false,
"HandlerArn": {
- "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A7011c612be80bca7973713bb9924f79b406",
+ "Ref": "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701f6dda04ffcec81d842b5ccc65a7d6f5f",
},
"InvocationType": "RequestResponse",
"ServiceToken": {
@@ -11921,11 +11845,7 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "Custom::Trigger",
"UpdateReplacePolicy": "Delete",
},
- "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A7011c612be80bca7973713bb9924f79b406": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionCurrentVersionA8B4A701f6dda04ffcec81d842b5ccc65a7d6f5f": {
"Metadata": {
"aws:cdk:do-not-refactor": true,
},
@@ -11938,8 +11858,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionEB7112AF": {
"DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218",
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A",
],
@@ -11951,9 +11869,9 @@ Direct link to Lambda function: /lambda/home#/functions/",
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "7301756f4001c608471bffd8c435a6d82d1bb8be6f5c44ccba0087649bcf8bc0.zip",
+ "S3Key": "9b619d8252f69c727b70d72add5b64f237cd672709297c7f2c4f0d04abb45002.zip",
},
- "Description": "[dev/ConstructHub/Sources/NpmJs] Copies the known versions from the staging bucket to the known versions table",
+ "Description": "[dev/ConstructHub/Sources/NpmJs/KnownVersionsMigration] Copies the known versions from the staging bucket to the known versions table",
"Environment": {
"Variables": {
"BUCKET_NAME": {
@@ -11981,10 +11899,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::Lambda::Function",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleAA17733A": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -12016,10 +11930,6 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsKnownVersionsMigrationFunctionServiceRoleDefaultPolicy80D50218": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -12125,8 +12035,8 @@ Direct link to Lambda function: /lambda/home#/functions/",
"Fn::Join": [
"",
[
- "The packument processor function is failing (errors or time-outs). Requests in the
-packument queue use up their attempts while it fails, and may be given up on early.
+ "The packument processor function is failing (errors or time-outs). Requests that keep
+failing it move to the packument dead-letter queue.
Link to the lambda function: /lambda/home#/functions/",
{
@@ -12160,19 +12070,49 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"ConstructHubSourcesNpmJsPackumentProcessorLaggyPackumentLagHigh863AFDFC": {
"Properties": {
- "AlarmDescription": "Laggy packuments take unusually long to catch up: the npm registry serves older revisions
-than the CouchDB changes feed announced, for hours. This usually means the registry has an
-outage or is far behind the feed. The packument processor keeps re-checking these packages.
+ "AlarmDescription": "The npm registry takes unusually long to serve the revisions the CouchDB changes feed
+announced: for hours. This usually means the registry has an outage or is far behind the
+feed. The packument processor keeps re-checking these packages.
Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
"AlarmName": "dev/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": 1,
"ExtendedStatistic": "p90",
- "MetricName": "LaggyPackumentLag",
+ "MetricName": "PackumentDelay",
"Namespace": "ConstructHub/PackageSource/NpmJs/Follower",
"Period": 10800,
- "Threshold": 21600000,
+ "Threshold": 21600,
+ "TreatMissingData": "notBreaching",
+ },
+ "Type": "AWS::CloudWatch::Alarm",
+ },
+ "ConstructHubSourcesNpmJsPackumentProcessorPendingPackumentsHighB797F54C": {
+ "Properties": {
+ "AlarmDescription": "An unusually high number of packages wait for the npm registry to serve the revision the
+CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage
+or is far behind the feed. The packument processor keeps re-checking these packages.
+
+Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runbook.md",
+ "AlarmName": "dev/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh",
+ "ComparisonOperator": "GreaterThanThreshold",
+ "Dimensions": [
+ {
+ "Name": "QueueName",
+ "Value": {
+ "Fn::GetAtt": [
+ "ConstructHubSourcesPackumentProcessorQueue34BDE578",
+ "QueueName",
+ ],
+ },
+ },
+ ],
+ "EvaluationPeriods": 3,
+ "MetricName": "ApproximateNumberOfMessagesNotVisible",
+ "Namespace": "AWS/SQS",
+ "Period": 3600,
+ "Statistic": "Minimum",
+ "Threshold": 2000,
"TreatMissingData": "notBreaching",
},
"Type": "AWS::CloudWatch::Alarm",
@@ -12222,10 +12162,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::Lambda::Permission",
},
"ConstructHubSourcesNpmJsServiceRoleAC3F7AA6": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@@ -12257,10 +12193,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Type": "AWS::IAM::Role",
},
"ConstructHubSourcesNpmJsServiceRoleDefaultPolicy65FBFA22": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
"Properties": {
"PolicyDocument": {
"Statement": [
@@ -12339,126 +12271,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
],
},
- {
- "Action": [
- "dynamodb:BatchGetItem",
- "dynamodb:Query",
- "dynamodb:GetItem",
- "dynamodb:Scan",
- "dynamodb:ConditionCheckItem",
- "dynamodb:BatchWriteItem",
- "dynamodb:PutItem",
- "dynamodb:UpdateItem",
- "dynamodb:DeleteItem",
- "dynamodb:DescribeTable",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "dynamodb:GetRecords",
- "dynamodb:GetShardIterator",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesKnownVersions1480B28B",
- "Arn",
- ],
- },
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubDenyListBucket1B3C2C2E",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": [
- "s3:GetObject*",
- "s3:GetBucket*",
- "s3:List*",
- ],
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubLicenseListBucket9334047F",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- ],
- },
- {
- "Action": "lambda:InvokeFunction",
- "Effect": "Allow",
- "Resource": [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- {
- "Fn::Join": [
- "",
- [
- {
- "Fn::GetAtt": [
- "ConstructHubSourcesNpmJsStageAndNotify591C0CFA",
- "Arn",
- ],
- },
- ":*",
- ],
- ],
- },
- ],
- },
{
"Action": [
"sqs:SendMessage",
@@ -12498,7 +12310,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "2e0070c3ad67732b1d20b42f0ebba4cac975f13681fe785dbda2a355319e1c01.zip",
+ "S3Key": "c47e2e7a8f6fed2a7f8614649353767f82be1cb59f9792de8ff448a676948125.zip",
},
"DeadLetterConfig": {
"TargetArn": {
@@ -12829,7 +12641,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Properties": {
"KmsMasterKeyId": "alias/aws/sqs",
"MessageRetentionPeriod": 1209600,
- "VisibilityTimeout": 1800,
},
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
@@ -12838,6 +12649,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
"ConstructHubLicenseListCustomResource323F0FD4",
+ "ConstructHubSourcesNpmJsKnownVersionsMigrationBeforeFollowerUpdateF06D8619",
"ConstructHubSourcesPackumentProcessorFunctionServiceRoleDefaultPolicy4D1F4AD4",
"ConstructHubSourcesPackumentProcessorFunctionServiceRole384F57F3",
],
@@ -12849,7 +12661,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-\${AWS::Region}",
},
- "S3Key": "630d91c0090957d6232d58ca5e9b6b0d55a2ca2b654d8ef37b7f9f20faa9697c.zip",
+ "S3Key": "6b3023d10890a8d4c79a7cb82848d9226f1fbf5196fb7c0deb2d549590bc79da.zip",
},
"Description": "[dev/ConstructHub/Sources/PackumentProcessor] Processes packages from the npm registry, retrying until the registry serves the revision announced by the changes feed",
"Environment": {
@@ -12869,12 +12681,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Ref": "ConstructHubLicenseListBucket9334047F",
},
"LICENSE_LIST_OBJECT_KEY": "allowed-licenses.json",
- "PACKUMENT_DEAD_LETTER_QUEUE_ARN": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
"PACKUMENT_QUEUE_URL": {
"Ref": "ConstructHubSourcesPackumentProcessorQueue34BDE578",
},
@@ -12963,22 +12769,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
],
},
},
- {
- "Action": [
- "sqs:ReceiveMessage",
- "sqs:ChangeMessageVisibility",
- "sqs:GetQueueUrl",
- "sqs:DeleteMessage",
- "sqs:GetQueueAttributes",
- ],
- "Effect": "Allow",
- "Resource": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- },
{
"Action": [
"dynamodb:BatchGetItem",
@@ -13111,28 +12901,6 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
},
"Type": "AWS::IAM::Policy",
},
- "ConstructHubSourcesPackumentProcessorFunctionSqsEventSourcedevConstructHubSourcesPackumentProcessorDLQBB0F158EFDD9B731": {
- "DependsOn": [
- "ConstructHubLicenseListAwsCliLayer59592811",
- "ConstructHubLicenseListCustomResource323F0FD4",
- ],
- "Properties": {
- "BatchSize": 10,
- "EventSourceArn": {
- "Fn::GetAtt": [
- "ConstructHubSourcesPackumentProcessorDLQF401BD77",
- "Arn",
- ],
- },
- "FunctionName": {
- "Ref": "ConstructHubSourcesPackumentProcessorFunction0E5F8177",
- },
- "FunctionResponseTypes": [
- "ReportBatchItemFailures",
- ],
- },
- "Type": "AWS::Lambda::EventSourceMapping",
- },
"ConstructHubSourcesPackumentProcessorFunctionSqsEventSourcedevConstructHubSourcesPackumentProcessorQueueB1811D0E3C6BE98A": {
"DependsOn": [
"ConstructHubLicenseListAwsCliLayer59592811",
@@ -13153,7 +12921,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"ReportBatchItemFailures",
],
"ScalingConfig": {
- "MaximumConcurrency": 2,
+ "MaximumConcurrency": 10,
},
},
"Type": "AWS::Lambda::EventSourceMapping",
@@ -13170,7 +12938,7 @@ Runbook: https://github.com/cdklabs/construct-hub/blob/main/docs/operator-runboo
"Arn",
],
},
- "maxReceiveCount": 10,
+ "maxReceiveCount": 20,
},
"VisibilityTimeout": 1800,
},
diff --git a/src/__tests__/package-sources/npmjs.test.ts b/src/__tests__/package-sources/npmjs.test.ts
index 49f6a0aea..783d4fc35 100644
--- a/src/__tests__/package-sources/npmjs.test.ts
+++ b/src/__tests__/package-sources/npmjs.test.ts
@@ -34,10 +34,13 @@ test('creates a retained, backed-up, on-demand known versions table', () => {
});
});
-test('passes the known versions table to the follower', () => {
+test('passes the known versions table to the packument processor', () => {
const template = synth(new NpmJs());
template.hasResourceProperties('AWS::Lambda::Function', {
+ Description: Match.stringLikeRegexp(
+ 'Processes packages from the npm registry'
+ ),
Environment: {
Variables: Match.objectLike({
KNOWN_VERSIONS_TABLE_NAME: Match.anyValue(),
@@ -110,7 +113,7 @@ test('the known versions migration can be turned off', () => {
).toHaveLength(0);
});
-test('retries laggy packuments through a queue that moves give-ups to a dead-letter queue', () => {
+test('retries packuments through a queue, with a dead-letter queue as a backstop', () => {
const template = synth(new NpmJs());
const dlqs = template.findResources('AWS::SQS::Queue', {
@@ -123,7 +126,7 @@ test('retries laggy packuments through a queue that moves give-ups to a dead-let
deadLetterTargetArn: {
'Fn::GetAtt': [Match.stringLikeRegexp('PackumentProcessorDLQ'), 'Arn'],
},
- maxReceiveCount: 10,
+ maxReceiveCount: 20,
},
});
expect(
@@ -138,26 +141,35 @@ test('retries laggy packuments through a queue that moves give-ups to a dead-let
},
});
expect(Object.keys(processors)).toHaveLength(1);
+ const [processorId, processor] = Object.entries(processors)[0] as [
+ string,
+ any
+ ];
template.hasResourceProperties('AWS::Lambda::EventSourceMapping', {
- FunctionName: { Ref: Object.keys(processors)[0] },
+ FunctionName: { Ref: processorId },
BatchSize: 10,
FunctionResponseTypes: ['ReportBatchItemFailures'],
- ScalingConfig: { MaximumConcurrency: 2 },
+ ScalingConfig: { MaximumConcurrency: 10 },
});
- // The same function reads the dead-letter queue, to log give-ups.
- const mappings = Object.values(
+ // It only reads the main queue, which hides messages for longer than the
+ // function runs.
+ const queueIds = Object.values(
template.findResources('AWS::Lambda::EventSourceMapping', {
- Properties: { FunctionName: { Ref: Object.keys(processors)[0] } },
+ Properties: { FunctionName: { Ref: processorId } },
})
- ).map((mapping: any) => JSON.stringify(mapping.Properties.EventSourceArn));
- expect(mappings).toHaveLength(2);
- expect(mappings.some((arn) => arn.includes('PackumentProcessorDLQ'))).toBe(
- true
- );
+ ).map((mapping: any) => mapping.Properties.EventSourceArn['Fn::GetAtt'][0]);
+ expect(queueIds).toHaveLength(1);
+ expect(queueIds[0]).not.toContain('DLQ');
+ const queues = template.findResources('AWS::SQS::Queue');
+ for (const queueId of queueIds) {
+ // Unset means the SQS default of 30 seconds.
+ const visibility = queues[queueId].Properties.VisibilityTimeout ?? 30;
+ expect(visibility).toBeGreaterThanOrEqual(processor.Properties.Timeout);
+ }
// There is no alarm on the dead-letter queue (it is only graphed), and no
- // alarm on the give-up metric.
+ // alarm on give-ups.
const alarmNames = Object.values(
template.findResources('AWS::CloudWatch::Alarm')
).map((alarm: any) => String(alarm.Properties.AlarmName));
@@ -167,26 +179,30 @@ test('retries laggy packuments through a queue that moves give-ups to a dead-let
name.endsWith('DLQNotEmpty') && name.includes('PackumentProcessor')
)
).toBe(false);
- expect(
- alarmNames.some((name) => name.endsWith('LaggyPackumentGiveUps'))
- ).toBe(false);
+ expect(alarmNames.some((name) => name.includes('GiveUps'))).toBe(false);
- // A burst of missing packuments within 3 hours raises an alarm.
+ // Many packages waiting for the registry for 3 hours raise an alarm.
template.hasResourceProperties('AWS::CloudWatch::Alarm', {
- AlarmName: 'Test/ConstructHub/Sources/NpmJs/Follower/MissingPackumentsHigh',
- MetricName: 'MissingPackuments',
- Period: 3 * 60 * 60,
- Statistic: 'Sum',
- Threshold: 1_500,
+ AlarmName:
+ 'Test/ConstructHub/Sources/NpmJs/PackumentProcessor/PendingPackumentsHigh',
+ MetricName: 'ApproximateNumberOfMessagesNotVisible',
+ Namespace: 'AWS/SQS',
+ Period: 60 * 60,
+ Statistic: 'Minimum',
+ EvaluationPeriods: 3,
+ Threshold: 2_000,
});
- // So does a high laggy packument lag.
+ expect(
+ alarmNames.some((name) => name.endsWith('MissingPackumentsHigh'))
+ ).toBe(false);
+ // So does a high packument delay. The alarm keeps its name.
template.hasResourceProperties('AWS::CloudWatch::Alarm', {
AlarmName:
'Test/ConstructHub/Sources/NpmJs/PackumentProcessor/LaggyPackumentLagHigh',
- MetricName: 'LaggyPackumentLag',
+ MetricName: 'PackumentDelay',
Period: 3 * 60 * 60,
ExtendedStatistic: 'p90',
- Threshold: 6 * 60 * 60 * 1_000,
+ Threshold: 6 * 60 * 60,
});
// Processor failures raise a low severity alarm too.
@@ -204,32 +220,34 @@ test('retries laggy packuments through a queue that moves give-ups to a dead-let
});
});
-test('every queue the packument processor reads hides messages for longer than the function runs', () => {
+test('the follower only reads the feed and sends requests to the packument queue', () => {
const template = synth(new NpmJs());
- const [processorId, processor] = Object.entries(
- template.findResources('AWS::Lambda::Function', {
- Properties: {
- Description: Match.stringLikeRegexp(
- 'Processes packages from the npm registry'
- ),
- },
- })
- )[0] as [string, any];
- const queues = template.findResources('AWS::SQS::Queue');
- const mappings = Object.values(
- template.findResources('AWS::Lambda::EventSourceMapping', {
- Properties: { FunctionName: { Ref: processorId } },
- })
- ) as any[];
+ const followers = template.findResources('AWS::Lambda::Function', {
+ Properties: {
+ Description: Match.stringLikeRegexp('Periodically query npmjs.com'),
+ },
+ });
+ expect(Object.keys(followers)).toHaveLength(1);
+ const [follower] = Object.values(followers) as any[];
+ expect(Object.keys(follower.Properties.Environment.Variables).sort()).toEqual(
+ ['AWS_EMF_ENVIRONMENT', 'BUCKET_NAME', 'PACKUMENT_QUEUE_URL']
+ );
+ expect(follower.Properties.MemorySize).toBe(2_048);
- expect(mappings).toHaveLength(2);
- for (const mapping of mappings) {
- const queueId = mapping.Properties.EventSourceArn['Fn::GetAtt'][0];
- // Unset means the SQS default of 30 seconds.
- const visibility = queues[queueId].Properties.VisibilityTimeout ?? 30;
- expect(visibility).toBeGreaterThanOrEqual(processor.Properties.Timeout);
- }
+ // Its role has no access to the known versions table or the stager.
+ const roleRef = follower.Properties.Role['Fn::GetAtt'][0];
+ const policies = Object.values(
+ template.findResources('AWS::IAM::Policy')
+ ).filter((policy: any) =>
+ JSON.stringify(policy.Properties.Roles).includes(roleRef)
+ );
+ const actions = JSON.stringify(
+ policies.map((policy: any) => policy.Properties.PolicyDocument.Statement)
+ );
+ expect(actions).not.toContain('dynamodb:');
+ expect(actions).not.toContain('lambda:InvokeFunction');
+ expect(actions).toContain('sqs:SendMessage');
});
test('the billing mode of the known versions table is configurable', () => {
diff --git a/src/__tests__/package-sources/npmjs/npm-js-follower.lambda.test.ts b/src/__tests__/package-sources/npmjs/npm-js-follower.lambda.test.ts
index 7892b6068..7a0297f93 100644
--- a/src/__tests__/package-sources/npmjs/npm-js-follower.lambda.test.ts
+++ b/src/__tests__/package-sources/npmjs/npm-js-follower.lambda.test.ts
@@ -1,20 +1,10 @@
-import { gunzipSync, gzipSync } from 'zlib';
+import { gunzipSync } from 'zlib';
import {
- BatchWriteItemCommand,
- DynamoDBClient,
- QueryCommand,
-} from '@aws-sdk/client-dynamodb';
-import { InvokeCommand, LambdaClient } from '@aws-sdk/client-lambda';
-import {
- GetObjectCommand,
PutObjectCommand,
+ GetObjectCommand,
S3Client,
} from '@aws-sdk/client-s3';
-import {
- GetQueueAttributesCommand,
- SendMessageBatchCommand,
- SQSClient,
-} from '@aws-sdk/client-sqs';
+import { SendMessageBatchCommand, SQSClient } from '@aws-sdk/client-sqs';
import type { metricScope, MetricsLogger } from 'aws-embedded-metrics';
import { Unit } from 'aws-embedded-metrics';
import type { Context, ScheduledEvent } from 'aws-lambda';
@@ -22,17 +12,10 @@ import { mockClient } from 'aws-sdk-client-mock';
import 'aws-sdk-client-mock-jest';
import nock from 'nock';
import {
- ENV_DENY_LIST_BUCKET_NAME,
- ENV_DENY_LIST_OBJECT_KEY,
-} from '../../../backend/deny-list/constants';
-import { EnvironmentVariables as LicenseListEnv } from '../../../backend/license-list/constants';
-import {
- ENV_KNOWN_VERSIONS_TABLE_NAME,
ENV_PACKUMENT_QUEUE_URL,
FOLLOWER_STATE_FILE_NAME,
MARKER_FILE_NAME,
MetricName,
- PACKUMENT_INITIAL_DELAY_SECONDS,
} from '../../../package-sources/npmjs/constants.lambda-shared';
import { FollowerState } from '../../../package-sources/npmjs/follower-state.lambda-shared';
import { handler } from '../../../package-sources/npmjs/npm-js-follower.lambda';
@@ -61,23 +44,14 @@ mockMetricScope.mockImplementation((cb) => {
});
const REPLICA = 'https://replicate.npmjs.com';
-const REGISTRY = 'https://registry.npmjs.org';
const MOCK_BUCKET = 'mock-staging-bucket';
-const MOCK_STAGING_FUNCTION = 'mock-staging-function';
-const MOCK_KNOWN_VERSIONS_TABLE = 'mock-known-versions-table';
const MOCK_PACKUMENT_QUEUE_URL =
'https://sqs.us-east-1.amazonaws.com/123456789012/mock-packument-queue';
-const MOCK_DENY_LIST_BUCKET = 'deny-list-bucket-name';
-const MOCK_DENY_LIST_OBJECT = 'my-deny-list.json';
-const MOCK_LICENSE_LIST_BUCKET = 'license-list-bucket-name';
-const MOCK_LICENSE_LIST_OBJECT = 'license-list.json';
const HOUR = 60 * 60 * 1_000;
const mockS3 = mockClient(S3Client);
-const mockLambda = mockClient(LambdaClient);
-const mockDynamoDB = mockClient(DynamoDBClient);
const mockSQS = mockClient(SQSClient);
const context: Context = {
@@ -91,66 +65,23 @@ const event: ScheduledEvent = {} as any;
beforeEach(() => {
mockS3.reset();
- mockLambda.reset();
- mockDynamoDB.reset();
mockSQS.reset();
mockPutMetric.mockClear();
process.env.BUCKET_NAME = MOCK_BUCKET;
- process.env.FUNCTION_NAME = MOCK_STAGING_FUNCTION;
- process.env[ENV_KNOWN_VERSIONS_TABLE_NAME] = MOCK_KNOWN_VERSIONS_TABLE;
process.env[ENV_PACKUMENT_QUEUE_URL] = MOCK_PACKUMENT_QUEUE_URL;
- process.env[ENV_DENY_LIST_BUCKET_NAME] = MOCK_DENY_LIST_BUCKET;
- process.env[ENV_DENY_LIST_OBJECT_KEY] = MOCK_DENY_LIST_OBJECT;
- process.env[LicenseListEnv.BUCKET_NAME] = MOCK_LICENSE_LIST_BUCKET;
- process.env[LicenseListEnv.OBJECT_KEY] = MOCK_LICENSE_LIST_OBJECT;
- // Empty deny list
- mockS3
- .on(GetObjectCommand, {
- Bucket: MOCK_DENY_LIST_BUCKET,
- Key: MOCK_DENY_LIST_OBJECT,
- })
- .resolves({ Body: stringToStream(JSON.stringify({})) });
- // License list allowing Apache-2.0
- mockS3
- .on(GetObjectCommand, {
- Bucket: MOCK_LICENSE_LIST_BUCKET,
- Key: MOCK_LICENSE_LIST_OBJECT,
- })
- .resolves({ Body: stringToStream(JSON.stringify(['Apache-2.0'])) });
// No legacy marker by default
mockS3
.on(GetObjectCommand, { Bucket: MOCK_BUCKET, Key: MARKER_FILE_NAME })
.rejects(noSuchKey());
-
- // Empty known versions table
- mockDynamoDB.on(QueryCommand).resolves({ Items: [] });
- mockDynamoDB.on(BatchWriteItemCommand).resolves({ UnprocessedItems: {} });
-
- // Empty packument queue
- mockSQS.on(SendMessageBatchCommand).resolves({ Successful: [], Failed: [] });
- mockSQS.on(GetQueueAttributesCommand).resolves({
- Attributes: {
- ApproximateNumberOfMessages: '0',
- ApproximateNumberOfMessagesNotVisible: '0',
- ApproximateNumberOfMessagesDelayed: '0',
- },
- });
-
mockS3.on(PutObjectCommand).resolves({});
- mockLambda.on(InvokeCommand).resolves({ StatusCode: 202 });
+ mockSQS.on(SendMessageBatchCommand).resolves({ Successful: [], Failed: [] });
});
afterEach(() => {
delete process.env.BUCKET_NAME;
- delete process.env.FUNCTION_NAME;
- delete process.env[ENV_KNOWN_VERSIONS_TABLE_NAME];
delete process.env[ENV_PACKUMENT_QUEUE_URL];
- delete process.env[ENV_DENY_LIST_BUCKET_NAME];
- delete process.env[ENV_DENY_LIST_OBJECT_KEY];
- delete process.env[LicenseListEnv.BUCKET_NAME];
- delete process.env[LicenseListEnv.OBJECT_KEY];
nock.cleanAll();
});
@@ -191,6 +122,17 @@ function givenLegacyMarker(marker: number) {
.resolves({ Body: stringToStream(JSON.stringify({ marker })) });
}
+function givenChanges(since: number, results: object[], lastSeq: number): void {
+ nock(REPLICA)
+ .get('/registry/_changes')
+ .query({ limit: '10000', since: String(since) })
+ .reply(200, { results, last_seq: lastSeq });
+}
+
+function change(seq: number, id: string, rev = '1-aaaaaa', deleted = false) {
+ return { seq, id, changes: [{ rev }], deleted };
+}
+
function savedState(): FollowerState {
const calls = mockS3
.commandCalls(PutObjectCommand)
@@ -204,81 +146,57 @@ function savedState(): FollowerState {
return FollowerState.fromText(body.toString('utf-8'));
}
-function packageDoc(name: string, rev: string, ...versions: string[]) {
- const time: Record = {
- created: '2023-01-01T00:00:00.000Z',
- modified: '2023-06-01T00:00:00.000Z',
- };
- const versionInfos: Record = {};
- for (const [i, version] of versions.entries()) {
- time[version] = `2023-06-01T00:0${i}:00.000Z`;
- versionInfos[version] = {
- dependencies: { constructs: '^10.0.0' },
- dist: {
- shasum: 'mock-shasum',
- tarball: `${REGISTRY}/${name}/-/${name}-${version}.tgz`,
- },
- jsii: {},
- keywords: ['cdk'],
- license: 'Apache-2.0',
- name,
- version,
- };
- }
- return {
- _id: name,
- _rev: rev,
- 'dist-tags': { latest: versions[versions.length - 1] },
- name,
- time,
- versions: versionInfos,
- };
+function statePutCount(): number {
+ return mockS3
+ .commandCalls(PutObjectCommand)
+ .filter((call) => call.args[0].input.Key === FOLLOWER_STATE_FILE_NAME)
+ .length;
}
-function stagedPackages(): Array<{ name: string; version: string }> {
- return mockLambda.commandCalls(InvokeCommand).map((call) => {
- const payload = JSON.parse(
- Buffer.from(call.args[0].input.Payload! as Uint8Array).toString('utf-8')
- );
- return { name: payload.name, version: payload.version };
- });
+/** The packument requests sent to the packument queue. */
+function queuedRequests(): any[] {
+ return mockSQS.commandCalls(SendMessageBatchCommand).flatMap((call) =>
+ call.args[0].input.Entries!.map((entry) => ({
+ ...JSON.parse(entry.MessageBody!),
+ delaySeconds: entry.DelaySeconds,
+ }))
+ );
}
-test('seeds from the legacy marker and processes fresh changes', async () => {
+test('seeds from the legacy marker and queues fresh changes', async () => {
givenHead(1_010);
givenNoStateFile();
givenLegacyMarker(1_000);
-
// The scan starts at the seeded marker position and finds one new entry.
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '1000' })
- .reply(200, {
- results: [
- {
- seq: 1_005,
- id: 'fresh-package',
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- },
- ],
- last_seq: 1_005,
- });
- nock(REGISTRY)
- .get('/fresh-package')
- .reply(200, packageDoc('fresh-package', '1-aaaaaa', '1.0.0'));
+ givenChanges(1_000, [change(1_005, 'fresh-package', '3-aaaaaa')], 1_005);
+ const before = Date.now();
await handler(event, context);
- expect(stagedPackages()).toEqual([
- { name: 'fresh-package', version: '1.0.0' },
- ]);
+ // The follower queues the change for the packument processor, right away.
+ const [request] = queuedRequests();
+ expect(request).toMatchObject({
+ name: 'fresh-package',
+ expectedRev: 3,
+ seq: 1_005,
+ delaySeconds: 0,
+ });
+ expect(request.reason).toBeUndefined();
+ expect(request.firstSeen).toBeGreaterThanOrEqual(before);
+ expect(mockSQS).toHaveReceivedCommandWith(SendMessageBatchCommand, {
+ QueueUrl: MOCK_PACKUMENT_QUEUE_URL,
+ });
// Entries above the previously covered position are fresh, not late.
expect(mockPutMetric).toHaveBeenCalledWith(
MetricName.LATE_CHANGE_COUNT,
0,
Unit.Count
);
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.CHANGE_COUNT,
+ 1,
+ Unit.Count
+ );
const state = savedState();
expect(state.has(1_005)).toBe(true);
@@ -288,7 +206,7 @@ test('seeds from the legacy marker and processes fresh changes', async () => {
expect(state.lastDeepScanAt).toBeDefined();
});
-test('discovers and stages late-inserted changes', async () => {
+test('discovers and queues late-inserted changes', async () => {
const now = Date.now();
givenHead(1_000);
@@ -302,36 +220,21 @@ test('discovers and stages late-inserted changes', async () => {
state.completeDeepScan(now - 2 * HOUR);
givenStateFile(state);
- // Regular scan: floor is the checkpoint at/bordering (now - window), i.e.
- // seq 500. Only the late entry's packument may be fetched.
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '500' })
- .reply(200, {
- results: [
- {
- seq: 550,
- id: 'already-seen-package',
- changes: [{ rev: '1-cccccc' }],
- deleted: false,
- },
- {
- seq: 600,
- id: 'late-package',
- changes: [{ rev: '2-dddddd' }],
- deleted: false,
- },
- ],
- last_seq: 600,
- });
- nock(REGISTRY)
- .get('/late-package')
- .reply(200, packageDoc('late-package', '2-dddddd', '1.2.3'));
+ // Regular scan: the floor is the checkpoint at (now - window), seq 500.
+ givenChanges(
+ 500,
+ [
+ change(550, 'already-seen-package'),
+ change(600, 'late-package', '2-dddddd'),
+ ],
+ 600
+ );
await handler(event, context);
- expect(stagedPackages()).toEqual([
- { name: 'late-package', version: '1.2.3' },
+ // Only the entry without a receipt is queued.
+ expect(queuedRequests()).toEqual([
+ expect.objectContaining({ name: 'late-package', seq: 600 }),
]);
expect(mockPutMetric).toHaveBeenCalledWith(
MetricName.LATE_CHANGE_COUNT,
@@ -351,159 +254,28 @@ test('discovers and stages late-inserted changes', async () => {
expect(saved.newestCheckpointSeq()).toBe(1_000);
});
-/** The packument requests sent to the packument queue. */
-function queuedRequests(): any[] {
- return mockSQS.commandCalls(SendMessageBatchCommand).flatMap((call) =>
- call.args[0].input.Entries!.map((entry) => ({
- ...JSON.parse(entry.MessageBody!),
- delaySeconds: entry.DelaySeconds,
- }))
- );
-}
-
-test('laggy packument: processes served versions and sends it to the packument queue', async () => {
- givenHead(2_010);
- givenNoStateFile();
- givenLegacyMarker(2_000);
-
- // The feed announces rev 5, but the registry only serves rev 3.
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '2000' })
- .reply(200, {
- results: [
- {
- seq: 2_005,
- id: 'laggy-package',
- changes: [{ rev: '5-eeeeee' }],
- deleted: false,
- },
- ],
- last_seq: 2_005,
- });
- nock(REGISTRY)
- .get('/laggy-package')
- .reply(200, packageDoc('laggy-package', '3-ffffff', '1.0.0'));
- mockSQS.on(GetQueueAttributesCommand).resolves({
- Attributes: {
- ApproximateNumberOfMessages: '0',
- ApproximateNumberOfMessagesNotVisible: '0',
- ApproximateNumberOfMessagesDelayed: '1',
- },
- });
-
- const before = Date.now();
- await handler(event, context);
-
- // The versions the registry did serve are processed anyway.
- expect(stagedPackages()).toEqual([
- { name: 'laggy-package', version: '1.0.0' },
- ]);
- // ... and a request to check for rev 5 is queued, delayed.
- const [request] = queuedRequests();
- expect(request).toMatchObject({
- name: 'laggy-package',
- expectedRev: 5,
- seq: 2_005,
- reason: 'laggy',
- delaySeconds: PACKUMENT_INITIAL_DELAY_SECONDS,
- });
- expect(request.firstSeen).toBeGreaterThanOrEqual(before);
- expect(mockSQS).toHaveReceivedCommandWith(SendMessageBatchCommand, {
- QueueUrl: MOCK_PACKUMENT_QUEUE_URL,
- });
- // The gauge reports the size of the packument queue.
- expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.LAGGY_PACKUMENTS,
- 1,
- Unit.Count
- );
- // The receipt is recorded.
- expect(savedState().has(2_005)).toBe(true);
-});
-
-test('laggy packument: a failure to queue it leaves the entry without a receipt', async () => {
+test('a failure to queue a chunk leaves its entries without a receipt', async () => {
givenHead(2_010);
givenNoStateFile();
givenLegacyMarker(2_000);
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '2000' })
- .reply(200, {
- results: [
- {
- seq: 2_005,
- id: 'laggy-package',
- changes: [{ rev: '5-eeeeee' }],
- deleted: false,
- },
- ],
- last_seq: 2_005,
- });
- nock(REGISTRY)
- .get('/laggy-package')
- .reply(200, packageDoc('laggy-package', '3-ffffff', '1.0.0'));
+ givenChanges(2_000, [change(2_005, 'some-package')], 2_005);
mockSQS.on(SendMessageBatchCommand).rejects(new Error('network'));
await expect(handler(event, context)).rejects.toThrow(/network/);
- // The next run processes the entry again.
+ // The next run sends the entry again.
expect(savedState().has(2_005)).toBe(false);
});
-test('missing packument: a change entry the registry has no packument for yet is sent to the packument queue', async () => {
+test('an entry that announces no revision expects any packument', async () => {
givenHead(2_010);
givenNoStateFile();
givenLegacyMarker(2_000);
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '2000' })
- .reply(200, {
- results: [
- {
- seq: 2_005,
- id: 'brand-new-package',
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- },
- ],
- last_seq: 2_005,
- });
- nock(REGISTRY).get('/brand-new-package').reply(404, 'not found');
-
- await handler(event, context);
-
- expect(stagedPackages()).toEqual([]);
- expect(queuedRequests()).toEqual([
- expect.objectContaining({
- name: 'brand-new-package',
- expectedRev: 1,
- seq: 2_005,
- reason: 'missing',
- }),
- ]);
- expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.MISSING_PACKUMENTS,
- 1,
- Unit.Count
+ givenChanges(
+ 2_000,
+ [{ seq: 2_005, id: 'no-rev-package', changes: [], deleted: false }],
+ 2_005
);
- expect(savedState().has(2_005)).toBe(true);
-});
-
-test('missing packument: an entry that announces no revision expects any packument', async () => {
- givenHead(2_010);
- givenNoStateFile();
- givenLegacyMarker(2_000);
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '2000' })
- .reply(200, {
- results: [
- { seq: 2_005, id: 'no-rev-package', changes: [], deleted: false },
- ],
- last_seq: 2_005,
- });
- nock(REGISTRY).get('/no-rev-package').reply(404, 'not found');
await handler(event, context);
@@ -516,25 +288,15 @@ test('ignores change entries for deleted packages, as if they were not in the fe
givenHead(2_010);
givenNoStateFile();
givenLegacyMarker(2_000);
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '2000' })
- .reply(200, {
- results: [
- {
- seq: 2_005,
- id: 'deleted-package',
- changes: [{ rev: '3-aaaaaa' }],
- deleted: true,
- },
- ],
- last_seq: 2_005,
- });
+ givenChanges(
+ 2_000,
+ [change(2_005, 'deleted-package', '3-aaaaaa', true)],
+ 2_005
+ );
await handler(event, context);
- // No packument fetch (nock would fail on an unexpected request), nothing
- // queued, nothing counted, and no receipt.
+ // Nothing queued, nothing counted, and no receipt.
expect(queuedRequests()).toEqual([]);
expect(mockPutMetric).toHaveBeenCalledWith(
MetricName.CHANGE_COUNT,
@@ -548,29 +310,12 @@ test('seeds at the beginning of the feed on first deployment (automatic backfill
givenHead(1_010);
givenNoStateFile();
// No legacy marker either: this is a brand-new deployment.
-
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '0' })
- .reply(200, {
- results: [
- {
- seq: 1_005,
- id: 'historic-package',
- changes: [{ rev: '1-bbbbbb' }],
- deleted: false,
- },
- ],
- last_seq: 1_005,
- });
- nock(REGISTRY)
- .get('/historic-package')
- .reply(200, packageDoc('historic-package', '1-bbbbbb', '1.0.0'));
+ givenChanges(0, [change(1_005, 'historic-package')], 1_005);
await handler(event, context);
- expect(stagedPackages()).toEqual([
- { name: 'historic-package', version: '1.0.0' },
+ expect(queuedRequests()).toEqual([
+ expect.objectContaining({ name: 'historic-package' }),
]);
const state = savedState();
expect(state.has(1_005)).toBe(true);
@@ -599,12 +344,7 @@ test('records interim checkpoints so an interrupted scan resumes mid-window', as
.reply(200, () => {
remaining = 30_000; // exhaust the budget after this page
return {
- results: seqs.map((seq) => ({
- seq,
- id: `package-${seq}`,
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- })),
+ results: seqs.map((seq) => change(seq, `package-${seq}`)),
last_seq: 20_000,
};
});
@@ -615,108 +355,15 @@ test('records interim checkpoints so an interrupted scan resumes mid-window', as
(context as any).getRemainingTimeInMillis = () => 300_000;
}
- // Nothing needed staging (everything was receipted), and no packument was
- // fetched (no registry nock exists). The interim checkpoint was recorded,
- // so the next run resumes from seq 20000 instead of the floor.
- expect(mockLambda).not.toHaveReceivedCommand(InvokeCommand);
+ // Everything was receipted, so nothing was queued. The interim checkpoint
+ // was recorded, so the next run resumes from seq 20000 instead of the floor.
+ expect(mockSQS).not.toHaveReceivedCommand(SendMessageBatchCommand);
const saved = savedState();
expect(saved.newestCheckpointSeq()).toBe(20_000);
// The interrupted (deep) scan did not complete.
expect(saved.lastDeepScanAt).toBeUndefined();
});
-test('retries truncated gzip responses from the registry', async () => {
- givenHead(1_010);
- givenNoStateFile();
- givenLegacyMarker(1_000);
-
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '1000' })
- .reply(200, {
- results: [
- {
- seq: 1_005,
- id: 'flaky-package',
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- },
- ],
- last_seq: 1_005,
- });
- // First packument response is a truncated gzip body (Z_BUF_ERROR), the
- // retry succeeds.
- const fullBody = gzipSync(
- Buffer.from(
- JSON.stringify(packageDoc('flaky-package', '1-aaaaaa', '1.0.0'))
- )
- );
- nock(REGISTRY)
- .get('/flaky-package')
- .reply(200, fullBody.subarray(0, fullBody.length - 8), {
- 'content-encoding': 'gzip',
- });
- nock(REGISTRY)
- .get('/flaky-package')
- .reply(200, packageDoc('flaky-package', '1-aaaaaa', '1.0.0'));
-
- await handler(event, context);
-
- expect(stagedPackages()).toEqual([
- { name: 'flaky-package', version: '1.0.0' },
- ]);
- expect(savedState().has(1_005)).toBe(true);
-});
-
-test('does not receipt entries whose metadata fetch failed, so a later scan retries them', async () => {
- givenHead(1_010);
- givenNoStateFile();
- givenLegacyMarker(1_000);
-
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '1000' })
- .reply(200, {
- results: [
- {
- seq: 1_004,
- id: 'broken-package',
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- },
- {
- seq: 1_006,
- id: 'good-package',
- changes: [{ rev: '1-bbbbbb' }],
- deleted: false,
- },
- ],
- last_seq: 1_006,
- });
- // A client error is used so the request is not retried until the
- // transient-error deadline.
- nock(REGISTRY).get('/broken-package').reply(403, 'forbidden');
- nock(REGISTRY)
- .get('/good-package')
- .reply(200, packageDoc('good-package', '1-bbbbbb', '1.0.0'));
-
- await handler(event, context);
-
- // The healthy entry was processed and receipted; the failed one was not
- // receipted, so the next scan will retry it.
- expect(stagedPackages()).toEqual([
- { name: 'good-package', version: '1.0.0' },
- ]);
- const state = savedState();
- expect(state.has(1_006)).toBe(true);
- expect(state.has(1_004)).toBe(false);
- expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.METADATA_FETCH_FAILURES,
- 1,
- Unit.Count
- );
-});
-
test('persists its state even when the scan fails part-way', async () => {
givenHead(1_010);
givenNoStateFile();
@@ -735,59 +382,22 @@ test('persists its state even when the scan fails part-way', async () => {
expect(savedState().newestCheckpointSeq()).toBe(1_000);
});
-function nonConstructDoc(name: string) {
- return {
- _id: name,
- _rev: '1-aaaaaa',
- 'dist-tags': { latest: '1.0.0' },
- name,
- time: {
- created: '2023-01-01T00:00:00.000Z',
- modified: '2023-06-01T00:00:00.000Z',
- '1.0.0': '2023-06-01T00:00:00.000Z',
- },
- versions: {
- '1.0.0': {
- dist: { shasum: 'mock-shasum', tarball: `${REGISTRY}/${name}.tgz` },
- name,
- version: '1.0.0',
- },
- },
- };
-}
-
-function statePutCount(): number {
- return mockS3
- .commandCalls(PutObjectCommand)
- .filter((call) => call.args[0].input.Key === FOLLOWER_STATE_FILE_NAME)
- .length;
-}
-
-test('persists its progress after every processed chunk', async () => {
+test('persists its progress after every chunk', async () => {
givenHead(20_000);
givenNoStateFile();
givenLegacyMarker(1_000);
// 1,500 unreceipted entries: two chunks of work.
- const entries = Array.from({ length: 1_500 }, (_, i) => ({
- seq: 1_001 + i,
- id: `bulk-package-${i}`,
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- }));
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '1000' })
- .reply(200, { results: entries, last_seq: 2_500 });
- nock(REGISTRY)
- .persist()
- .get(/^\/bulk-package-\d+$/)
- .reply(200, (uri) => nonConstructDoc(uri.slice(1)));
+ const entries = Array.from({ length: 1_500 }, (_, i) =>
+ change(1_001 + i, `bulk-package-${i}`)
+ );
+ givenChanges(1_000, entries, 2_500);
await handler(event, context);
// One state save per chunk (2), plus the final save.
expect(statePutCount()).toBeGreaterThanOrEqual(3);
+ expect(queuedRequests()).toHaveLength(1_500);
const state = savedState();
expect(state.has(1_001)).toBe(true);
expect(state.has(2_500)).toBe(true);
@@ -798,20 +408,10 @@ test('stops between chunks when the time budget is exhausted, keeping completed
givenNoStateFile();
givenLegacyMarker(1_000);
- const entries = Array.from({ length: 1_500 }, (_, i) => ({
- seq: 1_001 + i,
- id: `bulk-package-${i}`,
- changes: [{ rev: '1-aaaaaa' }],
- deleted: false,
- }));
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '1000' })
- .reply(200, { results: entries, last_seq: 2_500 });
- nock(REGISTRY)
- .persist()
- .get(/^\/bulk-package-\d+$/)
- .reply(200, (uri) => nonConstructDoc(uri.slice(1)));
+ const entries = Array.from({ length: 1_500 }, (_, i) =>
+ change(1_001 + i, `bulk-package-${i}`)
+ );
+ givenChanges(1_000, entries, 2_500);
// Exhaust the budget as soon as the first chunk persists.
let remaining = 300_000;
@@ -827,8 +427,9 @@ test('stops between chunks when the time budget is exhausted, keeping completed
(context as any).getRemainingTimeInMillis = () => 300_000;
}
- // The first chunk (1,000 entries) was processed and persisted; the second
+ // The first chunk (1,000 entries) was queued and persisted; the second
// was not: its entries carry no receipt and no checkpoint moved past them.
+ expect(queuedRequests()).toHaveLength(1_000);
const state = savedState();
expect(state.has(1_001)).toBe(true);
expect(state.has(2_000)).toBe(true);
@@ -848,105 +449,12 @@ test('resets its position when the feed head regresses below the newest checkpoi
givenStateFile(state);
// After the reset, the scan starts from the new head.
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '3000' })
- .reply(200, { results: [], last_seq: 3_000 });
+ givenChanges(3_000, [], 3_000);
await handler(event, context);
- expect(mockLambda).not.toHaveReceivedCommand(InvokeCommand);
+ expect(mockSQS).not.toHaveReceivedCommand(SendMessageBatchCommand);
const saved = savedState();
expect(saved.newestCheckpointSeq()).toBe(3_000);
expect(saved.has(4_500)).toBe(false);
});
-
-//#region Known versions table
-function givenKnownVersionsInTable(name: string, versions: string[]) {
- mockDynamoDB
- .on(QueryCommand, {
- ExpressionAttributeValues: { ':name': { S: name } },
- })
- .resolves({
- Items: versions.map((version) => ({ version: { S: version } })),
- });
-}
-
-/** The `name@version` keys recorded in the table, sorted. */
-function recordedVersions(): string[] {
- return mockDynamoDB
- .commandCalls(BatchWriteItemCommand)
- .flatMap(
- (call) => call.args[0].input.RequestItems![MOCK_KNOWN_VERSIONS_TABLE]
- )
- .map(
- (request) =>
- `${request.PutRequest!.Item!.name.S}@${
- request.PutRequest!.Item!.version.S
- }`
- )
- .sort();
-}
-
-function givenOneChange(id: string, doc: object) {
- nock(REPLICA)
- .get('/registry/_changes')
- .query({ limit: '10000', since: '1000' })
- .reply(200, {
- results: [
- { seq: 1_005, id, changes: [{ rev: '1-aaaaaa' }], deleted: false },
- ],
- last_seq: 1_005,
- });
- nock(REGISTRY).get(`/${id}`).reply(200, doc);
-}
-
-test('stages only versions not recorded in the table, and records them', async () => {
- givenHead(1_010);
- givenNoStateFile();
- givenLegacyMarker(1_000);
- givenOneChange(
- 'known-package',
- packageDoc('known-package', '1-aaaaaa', '1.0.0', '1.1.0')
- );
- givenKnownVersionsInTable('known-package', ['1.0.0']);
-
- await handler(event, context);
-
- expect(stagedPackages()).toEqual([
- { name: 'known-package', version: '1.1.0' },
- ]);
- expect(recordedVersions()).toEqual(['known-package@1.1.0']);
-});
-
-test('records versions before the follower state, so a failed save never skips a version', async () => {
- givenHead(1_010);
- givenNoStateFile();
- givenLegacyMarker(1_000);
- givenOneChange(
- 'fresh-package',
- packageDoc('fresh-package', '1-aaaaaa', '1.0.0')
- );
- mockDynamoDB.on(BatchWriteItemCommand).rejects(new Error('network'));
-
- await expect(handler(event, context)).rejects.toThrow(/network/);
-
- // The chunk's receipts were not saved: the next run processes it again.
- const statePuts = mockS3
- .commandCalls(PutObjectCommand)
- .filter((call) => call.args[0].input.Key === FOLLOWER_STATE_FILE_NAME);
- expect(statePuts).toHaveLength(0);
-});
-
-test('does not query the table for packages without construct library versions', async () => {
- givenHead(1_010);
- givenNoStateFile();
- givenLegacyMarker(1_000);
- givenOneChange('boring-package', nonConstructDoc('boring-package'));
-
- await handler(event, context);
-
- expect(mockDynamoDB).not.toHaveReceivedCommand(QueryCommand);
- expect(mockLambda).not.toHaveReceivedCommand(InvokeCommand);
-});
-//#endregion
diff --git a/src/__tests__/package-sources/npmjs/packument-processor.lambda.test.ts b/src/__tests__/package-sources/npmjs/packument-processor.lambda.test.ts
index 4ec778c11..a9e580cfe 100644
--- a/src/__tests__/package-sources/npmjs/packument-processor.lambda.test.ts
+++ b/src/__tests__/package-sources/npmjs/packument-processor.lambda.test.ts
@@ -1,3 +1,4 @@
+import { gzipSync } from 'zlib';
import {
BatchWriteItemCommand,
DynamoDBClient,
@@ -5,7 +6,11 @@ import {
} from '@aws-sdk/client-dynamodb';
import { InvokeCommand, LambdaClient } from '@aws-sdk/client-lambda';
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
-import { ChangeMessageVisibilityCommand, SQSClient } from '@aws-sdk/client-sqs';
+import {
+ ChangeMessageVisibilityCommand,
+ SendMessageBatchCommand,
+ SQSClient,
+} from '@aws-sdk/client-sqs';
import type { metricScope, MetricsLogger } from 'aws-embedded-metrics';
import { Unit } from 'aws-embedded-metrics';
import type { Context, SQSEvent, SQSRecord } from 'aws-lambda';
@@ -19,9 +24,9 @@ import {
import { EnvironmentVariables as LicenseListEnv } from '../../../backend/license-list/constants';
import {
ENV_KNOWN_VERSIONS_TABLE_NAME,
- ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN,
ENV_PACKUMENT_QUEUE_URL,
MetricName,
+ PACKUMENT_MAX_AGE_MS,
PACKUMENT_MAX_RETRY_DELAY_SECONDS,
PACKUMENT_MIN_RETRY_DELAY_SECONDS,
} from '../../../package-sources/npmjs/constants.lambda-shared';
@@ -37,9 +42,12 @@ const mockMetricScope = require('aws-embedded-metrics')
const mockPutMetric = jest.fn() as jest.MockedFunction<
MetricsLogger['putMetric']
>;
+const mockSetDimensions = jest.fn() as jest.MockedFunction<
+ MetricsLogger['setDimensions']
+>;
const mockMetrics: MetricsLogger = {
putMetric: mockPutMetric,
- setDimensions: jest.fn(),
+ setDimensions: mockSetDimensions,
setProperty: jest.fn(),
} as any;
mockMetricScope.mockImplementation((cb) => {
@@ -51,7 +59,6 @@ const REGISTRY = 'https://registry.npmjs.org';
const QUEUE_URL =
'https://sqs.us-east-1.amazonaws.com/123456789012/mock-packument-queue';
const QUEUE_ARN = 'arn:aws:sqs:us-east-1:123456789012:mock-packument-queue';
-const DLQ_ARN = 'arn:aws:sqs:us-east-1:123456789012:mock-packument-dlq';
const MINUTE = 60 * 1_000;
const HOUR = 60 * MINUTE;
const TABLE = 'mock-known-versions-table';
@@ -74,10 +81,10 @@ beforeEach(() => {
mockDynamoDB.reset();
mockSQS.reset();
mockPutMetric.mockClear();
+ mockSetDimensions.mockClear();
process.env.FUNCTION_NAME = STAGING_FUNCTION;
process.env[ENV_PACKUMENT_QUEUE_URL] = QUEUE_URL;
- process.env[ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN] = DLQ_ARN;
// No jitter, unless a test says otherwise.
jest.spyOn(Math, 'random').mockReturnValue(0.5);
process.env[ENV_KNOWN_VERSIONS_TABLE_NAME] = TABLE;
@@ -99,13 +106,13 @@ beforeEach(() => {
mockDynamoDB.on(BatchWriteItemCommand).resolves({ UnprocessedItems: {} });
mockLambda.on(InvokeCommand).resolves({ StatusCode: 202 });
mockSQS.on(ChangeMessageVisibilityCommand).resolves({});
+ mockSQS.on(SendMessageBatchCommand).resolves({ Successful: [], Failed: [] });
});
afterEach(() => {
for (const name of [
'FUNCTION_NAME',
ENV_PACKUMENT_QUEUE_URL,
- ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN,
ENV_KNOWN_VERSIONS_TABLE_NAME,
ENV_DENY_LIST_BUCKET_NAME,
ENV_DENY_LIST_OBJECT_KEY,
@@ -121,12 +128,12 @@ afterEach(() => {
function record(
messageId: string,
request: Partial | string,
- { source = QUEUE_ARN, age = 0 }: { source?: string; age?: number } = {}
+ { age = 0, receiveCount = 1 }: { age?: number; receiveCount?: number } = {}
): SQSRecord {
return {
messageId,
receiptHandle: `receipt-${messageId}`,
- eventSourceARN: source,
+ eventSourceARN: QUEUE_ARN,
body:
typeof request === 'string'
? request
@@ -135,7 +142,7 @@ function record(
firstSeen: Date.now() - age,
...request,
}),
- attributes: { ApproximateReceiveCount: '1' },
+ attributes: { ApproximateReceiveCount: String(receiveCount) },
} as any;
}
@@ -200,11 +207,19 @@ test('completes a request once the registry serves the expected revision', async
]);
expect(mockDynamoDB).toHaveReceivedCommand(BatchWriteItemCommand);
expect(mockSQS).not.toHaveReceivedCommand(ChangeMessageVisibilityCommand);
+ expect(mockSQS).not.toHaveReceivedCommand(SendMessageBatchCommand);
expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.LAGGY_PACKUMENTS_RECOVERED,
- 1,
+ MetricName.FAILED_PACKUMENT_RETRIEVALS,
+ 0,
Unit.Count
);
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.NPMJS_CHANGE_AGE,
+ expect.any(Number),
+ Unit.Milliseconds
+ );
+ // Caught up on the first attempt: no delay.
+ expect(metricValues(MetricName.PACKUMENT_DELAY)).toEqual([]);
});
test('processes what is served, and waits as long as the request is old before the next attempt', async () => {
@@ -230,6 +245,13 @@ test('processes what is served, and waits as long as the request is old before t
ReceiptHandle: 'receipt-m1',
VisibilityTimeout: 40 * 60,
});
+ // The same message is checked again; nothing replaces it.
+ expect(mockSQS).not.toHaveReceivedCommand(SendMessageBatchCommand);
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.FAILED_PACKUMENT_RETRIEVALS,
+ 1,
+ Unit.Count
+ );
});
test('keeps the wait within the minimum and maximum delay', async () => {
@@ -282,7 +304,7 @@ test('retries a request while the registry has no packument for the package yet'
nock(REGISTRY).get('/not-yet').reply(404, 'not found');
const result = await handler(
- event(record('m1', { name: 'not-yet', expectedRev: 1, reason: 'missing' })),
+ event(record('m1', { name: 'not-yet', expectedRev: 1 })),
context
);
@@ -291,6 +313,11 @@ test('retries a request while the registry has no packument for the package yet'
VisibilityTimeout: PACKUMENT_MIN_RETRY_DELAY_SECONDS,
});
expect(stagedPackages()).toEqual([]);
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.FAILED_PACKUMENT_RETRIEVALS,
+ 1,
+ Unit.Count
+ );
});
test('retries a request that failed with an error, without failing the others', async () => {
@@ -313,6 +340,17 @@ test('retries a request that failed with an error, without failing the others',
{ itemIdentifier: 'm3' },
]);
expect(stagedPackages()).toEqual([{ name: 'fine', version: '1.0.0' }]);
+ // The invalid message is not a failed retrieval.
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.FAILED_PACKUMENT_RETRIEVALS,
+ 1,
+ Unit.Count
+ );
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.METADATA_FETCH_FAILURES,
+ 1,
+ Unit.Count
+ );
});
test('does not stage versions that are already known', async () => {
@@ -373,126 +411,293 @@ test('checks caught-up packages again when their versions could not be recorded'
});
});
-test('reports how long laggy packuments took to catch up', async () => {
+test('reports how long a packument took to arrive when it caught up on a later attempt', async () => {
nock(REGISTRY)
.get('/caught-up')
.reply(200, packageDoc('caught-up', '5-aaaaaa', '1.0.0'));
await handler(
event(
- record('m1', { name: 'caught-up', expectedRev: 5 }, { age: 2 * HOUR })
+ record(
+ 'm1',
+ { name: 'caught-up', expectedRev: 5 },
+ { age: 2 * HOUR, receiveCount: 4 }
+ )
),
context
);
- const lag = mockPutMetric.mock.calls.find(
- ([name]) => name === MetricName.LAGGY_PACKUMENT_LAG
+ const [delay] = metricValues(MetricName.PACKUMENT_DELAY);
+ expect(delay).toBeGreaterThanOrEqual(2 * 3_600);
+ expect(delay).toBeLessThan(2 * 3_600 + 60);
+ expect(mockPutMetric).toHaveBeenCalledWith(
+ MetricName.PACKUMENT_DELAY,
+ delay,
+ Unit.Seconds
);
- expect(lag?.[1]).toBeGreaterThanOrEqual(2 * HOUR);
- expect(lag?.[2]).toBe(Unit.Milliseconds);
});
-test('counts missing packuments that arrived separately from laggy ones, without a lag', async () => {
+test('reads requests sent by earlier versions, ignoring their reason', async () => {
nock(REGISTRY)
- .get('/arrived')
- .reply(200, packageDoc('arrived', '1-aaaaaa', '1.0.0'));
+ .get('/old-request')
+ .reply(200, packageDoc('old-request', '5-aaaaaa', '1.0.0'));
- await handler(
- event(record('m1', { name: 'arrived', expectedRev: 1, reason: 'missing' })),
+ const result = await handler(
+ event(
+ record(
+ 'm1',
+ JSON.stringify({
+ name: 'old-request',
+ expectedRev: 5,
+ firstSeen: Date.now(),
+ reason: 'missing',
+ })
+ )
+ ),
context
);
- expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.MISSING_PACKUMENTS_RECOVERED,
- 1,
- Unit.Count
- );
- expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.LAGGY_PACKUMENTS_RECOVERED,
- 0,
- Unit.Count
- );
- expect(mockPutMetric).not.toHaveBeenCalledWith(
- MetricName.LAGGY_PACKUMENT_LAG,
- expect.anything(),
- expect.anything()
- );
+ expect(result.batchItemFailures).toEqual([]);
+ expect(stagedPackages()).toEqual([{ name: 'old-request', version: '1.0.0' }]);
});
-describe('dead-letter queue', () => {
- test('logs, counts and deletes requests that were given up on, without checking them', async () => {
- const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
+describe('giving up', () => {
+ const OLD = PACKUMENT_MAX_AGE_MS + MINUTE;
+
+ beforeEach(() => {
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
+ });
+
+ test('a request older than a day is given up on when the registry is still behind, after processing what it serves', async () => {
+ nock(REGISTRY)
+ .get('/stuck')
+ .reply(200, packageDoc('stuck', '3-aaaaaa', '1.0.0'));
const result = await handler(
event(
record(
'm1',
{ name: 'stuck', expectedRev: 5 },
- { source: DLQ_ARN, age: 29 * HOUR }
- ),
- record(
- 'm2',
- { name: 'never-arrived', expectedRev: 1, reason: 'missing' },
- { source: DLQ_ARN }
+ { age: OLD, receiveCount: 12 }
)
),
context
);
- // Deleted (no fetch: nock would reject one).
expect(result.batchItemFailures).toEqual([]);
expect(mockSQS).not.toHaveReceivedCommand(ChangeMessageVisibilityCommand);
- expect(stagedPackages()).toEqual([]);
- expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.LAGGY_PACKUMENT_GIVE_UPS,
- 1,
- Unit.Count
+ expect(stagedPackages()).toEqual([{ name: 'stuck', version: '1.0.0' }]);
+ expect(giveUps()).toEqual({ Laggy: 1 });
+ expect(console.warn).toHaveBeenCalledWith(
+ expect.stringContaining(
+ 'Giving up on stuck: the registry still serves rev 3, not rev 5'
+ )
);
+ });
+
+ test('the last check decides the reason', async () => {
+ nock(REGISTRY).get('/never-arrived').reply(404, 'not found');
+ nock(REGISTRY).get('/unreachable').reply(403, 'forbidden');
+
+ const result = await handler(
+ event(
+ record('m1', { name: 'never-arrived', expectedRev: 1 }, { age: OLD }),
+ record('m2', { name: 'unreachable', expectedRev: 1 }, { age: OLD })
+ ),
+ context
+ );
+
+ expect(result.batchItemFailures).toEqual([]);
+ expect(giveUps()).toEqual({ Missing: 1, Unreachable: 1 });
+ });
+
+ test('give-ups are counted by reason and in total', async () => {
+ nock(REGISTRY).get('/never-arrived').reply(404, 'not found');
+
+ await handler(
+ event(
+ record('m1', { name: 'never-arrived', expectedRev: 1 }, { age: OLD })
+ ),
+ context
+ );
+
+ expect(mockSetDimensions).toHaveBeenCalledWith([{ Reason: 'Missing' }, {}]);
expect(mockPutMetric).toHaveBeenCalledWith(
- MetricName.MISSING_PACKUMENT_GIVE_UPS,
+ MetricName.PACKUMENT_GIVE_UPS,
1,
Unit.Count
);
- const lag = mockPutMetric.mock.calls.find(
- ([name]) => name === MetricName.LAGGY_PACKUMENT_LAG
- );
- expect(lag?.[1]).toBeGreaterThanOrEqual(29 * HOUR);
- expect(warn).toHaveBeenCalledWith(
- expect.stringContaining('Giving up on laggy packument for stuck')
+ });
+
+ test('a request older than a day that catches up is done, not given up on', async () => {
+ nock(REGISTRY)
+ .get('/late')
+ .reply(200, packageDoc('late', '5-aaaaaa', '1.0.0'));
+
+ await handler(
+ event(
+ record(
+ 'm1',
+ { name: 'late', expectedRev: 5 },
+ { age: OLD, receiveCount: 12 }
+ )
+ ),
+ context
);
- expect(warn).toHaveBeenCalledWith(
- expect.stringContaining(
- 'Giving up on missing packument for never-arrived'
- )
+
+ expect(giveUps()).toEqual({});
+ expect(metricValues(MetricName.PACKUMENT_DELAY)).toHaveLength(1);
+ });
+
+ test('a request given up on is still checked again when its versions could not be recorded', async () => {
+ nock(REGISTRY)
+ .get('/stuck')
+ .reply(200, packageDoc('stuck', '3-aaaaaa', '1.0.0'));
+ mockDynamoDB
+ .on(BatchWriteItemCommand)
+ .rejects(new Error('dynamodb is down'));
+
+ const result = await handler(
+ event(record('m1', { name: 'stuck', expectedRev: 5 }, { age: OLD })),
+ context
);
+
+ expect(result.batchItemFailures).toEqual([{ itemIdentifier: 'm1' }]);
});
+});
- test('deletes an invalid request it was given up on', async () => {
- jest.spyOn(console, 'warn').mockImplementation(() => {});
+describe('processing', () => {
+ function changeRecord(
+ messageId: string,
+ name: string,
+ expectedRev: number
+ ): SQSRecord {
+ return record(messageId, { name, expectedRev, seq: 1_005 });
+ }
+
+ test('retries truncated gzip responses from the registry', async () => {
+ // The first response is a truncated gzip body (Z_BUF_ERROR), the retry
+ // succeeds.
+ const fullBody = gzipSync(
+ Buffer.from(
+ JSON.stringify(packageDoc('flaky-package', '1-aaaaaa', '1.0.0'))
+ )
+ );
+ nock(REGISTRY)
+ .get('/flaky-package')
+ .reply(200, fullBody.subarray(0, fullBody.length - 8), {
+ 'content-encoding': 'gzip',
+ });
+ nock(REGISTRY)
+ .get('/flaky-package')
+ .reply(200, packageDoc('flaky-package', '1-aaaaaa', '1.0.0'));
const result = await handler(
- event(record('m1', 'not json', { source: DLQ_ARN })),
+ event(changeRecord('m1', 'flaky-package', 1)),
context
);
expect(result.batchItemFailures).toEqual([]);
+ expect(stagedPackages()).toEqual([
+ { name: 'flaky-package', version: '1.0.0' },
+ ]);
});
- test('handles a batch from either queue on its own', async () => {
+ test('records the staged versions in the table', async () => {
nock(REGISTRY)
- .get('/caught-up')
- .reply(200, packageDoc('caught-up', '5-aaaaaa', '1.0.0'));
- jest.spyOn(console, 'warn').mockImplementation(() => {});
+ .get('/known-package')
+ .reply(200, packageDoc('known-package', '1-aaaaaa', '1.0.0', '1.1.0'));
+ mockDynamoDB
+ .on(QueryCommand)
+ .resolves({ Items: [{ version: { S: '1.0.0' } }] });
+
+ await handler(event(changeRecord('m1', 'known-package', 1)), context);
+
+ expect(stagedPackages()).toEqual([
+ { name: 'known-package', version: '1.1.0' },
+ ]);
+ const recorded = mockDynamoDB
+ .commandCalls(BatchWriteItemCommand)
+ .flatMap((call) => call.args[0].input.RequestItems![TABLE])
+ .map(
+ (request) =>
+ `${request.PutRequest!.Item!.name.S}@${
+ request.PutRequest!.Item!.version.S
+ }`
+ );
+ expect(recorded).toEqual(['known-package@1.1.0']);
+ });
+
+ test('does not query the table for packages without construct library versions', async () => {
+ nock(REGISTRY)
+ .get('/boring-package')
+ .reply(200, {
+ ...packageDoc('boring-package', '1-aaaaaa'),
+ time: {
+ created: '2023-01-01T00:00:00.000Z',
+ modified: '2023-06-01T00:00:00.000Z',
+ '1.0.0': '2023-06-01T00:00:00.000Z',
+ },
+ versions: {
+ '1.0.0': {
+ dist: { shasum: 'mock-shasum', tarball: `${REGISTRY}/b.tgz` },
+ name: 'boring-package',
+ version: '1.0.0',
+ },
+ },
+ });
+
+ await handler(event(changeRecord('m1', 'boring-package', 1)), context);
+
+ expect(mockDynamoDB).not.toHaveReceivedCommand(QueryCommand);
+ expect(stagedPackages()).toEqual([]);
+ });
+
+ test('skips packages last modified before constructs existed', async () => {
+ const doc = packageDoc('ancient-package', '1-aaaaaa', '1.0.0');
+ nock(REGISTRY)
+ .get('/ancient-package')
+ .reply(200, {
+ ...doc,
+ time: { ...doc.time, modified: '2015-01-01T00:00:00.000Z' },
+ });
const result = await handler(
- event(
- record('m1', { name: 'caught-up', expectedRev: 5 }),
- record('m2', { name: 'stuck', expectedRev: 5 }, { source: DLQ_ARN })
- ),
+ event(changeRecord('m1', 'ancient-package', 1)),
context
);
expect(result.batchItemFailures).toEqual([]);
- expect(stagedPackages()).toEqual([{ name: 'caught-up', version: '1.0.0' }]);
+ expect(stagedPackages()).toEqual([]);
});
});
+
+/** The values put for a metric, in order. */
+function metricValues(name: MetricName): number[] {
+ return mockPutMetric.mock.calls
+ .filter(([metric]) => metric === name)
+ .map(([, value]) => value as number);
+}
+
+/** The give-ups counted, by reason. */
+function giveUps(): Record {
+ const result: Record = {};
+ const puts = mockPutMetric.mock.calls.map((call, i) => ({
+ name: call[0],
+ value: call[1] as number,
+ order: mockPutMetric.mock.invocationCallOrder[i],
+ }));
+ mockSetDimensions.mock.calls.forEach(([sets], i) => {
+ const reason = Array.isArray(sets) ? sets[0]?.Reason : undefined;
+ if (reason == null) {
+ return;
+ }
+ // The give-up count put right after these dimensions were set.
+ const order = mockSetDimensions.mock.invocationCallOrder[i];
+ const put = puts.find(
+ (p) => p.order > order && p.name === MetricName.PACKUMENT_GIVE_UPS
+ );
+ result[reason] = (result[reason] ?? 0) + (put?.value ?? 0);
+ });
+ return result;
+}
diff --git a/src/metric-utils.ts b/src/metric-utils.ts
index 08a9cd282..661d811a5 100644
--- a/src/metric-utils.ts
+++ b/src/metric-utils.ts
@@ -1,4 +1,5 @@
import { createHash } from 'crypto';
+import { Token } from 'aws-cdk-lib';
import { MathExpression, Metric } from 'aws-cdk-lib/aws-cloudwatch';
/**
@@ -9,16 +10,13 @@ export function fillMetric(
metric: Metric,
value: number | 'REPEAT' = 0
): MathExpression {
- // We assume namespace + name is enough to uniquely identify a metric here.
- // This is true locally at this time, but in case this ever changes, consider
- // also processing dimensions and period.
- const h = createHash('sha256')
- .update(metric.namespace)
- .update('\0')
- .update(metric.metricName)
- .digest('hex');
-
- const metricName = `m${h}`;
+ // Token dimensions (resource references) are left out: their string form
+ // depends on construction order, so the id would not be stable.
+ const dimensions = Object.entries(metric.dimensions ?? {})
+ .filter(([, dimension]) => !Token.isUnresolved(dimension))
+ .sort();
+ const key = JSON.stringify([metric.namespace, metric.metricName, dimensions]);
+ const metricName = `m${createHash('sha256').update(key).digest('hex')}`;
return new MathExpression({
expression: `FILL(${metricName}, ${value})`,
diff --git a/src/package-sources/npmjs.ts b/src/package-sources/npmjs.ts
index 4cec8ec7c..f355bbdf0 100644
--- a/src/package-sources/npmjs.ts
+++ b/src/package-sources/npmjs.ts
@@ -24,7 +24,7 @@ import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
import { IFunction, Tracing } from 'aws-cdk-lib/aws-lambda';
import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
import { BlockPublicAccess, IBucket } from 'aws-cdk-lib/aws-s3';
-import { Queue, QueueEncryption } from 'aws-cdk-lib/aws-sqs';
+import { IQueue, Queue, QueueEncryption } from 'aws-cdk-lib/aws-sqs';
import { Construct } from 'constructs';
import { AlarmSeverity } from '../api';
import {
@@ -45,7 +45,6 @@ import type {
import { RUNBOOK_URL } from '../runbook-url';
import { NpmJsPackageCanary } from './npmjs/canary';
import {
- ENV_KNOWN_VERSIONS_TABLE_NAME,
FOLLOWER_STATE_FILE_NAME,
KNOWN_VERSIONS_FILE_NAME,
KnownVersionsAttribute,
@@ -84,17 +83,20 @@ const FOLLOWER_RUN_RATE = Duration.minutes(5);
const NO_CHANGES_ALARM_DURATION = Duration.hours(24);
/**
- * Alarm if more change entries than this had no packument in the registry
- * within 3 hours. In October 2026, a 3 hour window usually saw 170 of them,
- * and at most about 500. Well above that means a registry outage.
+ * Alarm if more packument requests than this wait for their next attempt for
+ * 3 hours. Each one is a package the registry has not served the announced
+ * revision for yet, counted once however often it was checked. In October
+ * 2026, a 3 hour window usually saw 170 missing packuments, and at most about
+ * 500, which stay in the queue for up to a day. Well above that means a
+ * registry outage.
*/
-const MISSING_PACKUMENTS_ALARM_THRESHOLD = 1_500;
+const PENDING_PACKUMENTS_ALARM_THRESHOLD = 2_000;
/**
- * Alarm if 90% of the laggy packuments that caught up (or were given up on)
- * within 3 hours took longer than this.
+ * Alarm if 90% of the packuments the registry served late, within 3 hours,
+ * took longer than this.
*/
-const LAGGY_PACKUMENT_LAG_ALARM_THRESHOLD = Duration.hours(6);
+const PACKUMENT_DELAY_ALARM_THRESHOLD = Duration.hours(6);
export interface NpmJsProps {
/**
@@ -271,10 +273,10 @@ export class NpmJs implements IPackageSource {
environment: {
AWS_EMF_ENVIRONMENT: 'Local',
BUCKET_NAME: bucket.bucketName,
- FUNCTION_NAME: stager.functionName,
- [ENV_KNOWN_VERSIONS_TABLE_NAME]: knownVersions.tableName,
},
- memorySize: 10_024, // 10 GiB
+ // The follower only reads the changes feed. The receipts it keeps in
+ // its state can take a few hundred MB during a backfill.
+ memorySize: 2_048,
reservedConcurrentExecutions: 1, // Only one execution at a time, to avoid race conditions on the S3 follower state object
timeout: FOLLOWER_RUN_RATE,
tracing: Tracing.ACTIVE,
@@ -284,22 +286,10 @@ export class NpmJs implements IPackageSource {
// deployments.
bucket.grantRead(follower, MARKER_FILE_NAME);
bucket.grantReadWrite(follower, FOLLOWER_STATE_FILE_NAME);
- knownVersions.grantReadWriteData(follower);
- if (this.props.enableKnownVersionsMigration ?? true) {
- new KnownVersionsTableMigration(follower, 'KnownVersionsMigration', {
- bucket,
- table: knownVersions,
- follower,
- });
- }
- denyList?.grantRead(follower);
- licenseList.grantRead(follower);
- stager.grantInvoke(follower);
-
- // Requests to process a package from the registry again, because the
- // registry served an older revision than the changes feed announced, or
- // no packument at all yet.
+ // Requests to process a package from the registry: one for every change
+ // entry the follower reads, and again while the registry lags behind the
+ // changes feed.
const packuments = new PackumentQueueProcessor(
scope,
'PackumentProcessor',
@@ -307,6 +297,14 @@ export class NpmJs implements IPackageSource {
);
packuments.grantSendRequests(follower);
+ if (this.props.enableKnownVersionsMigration ?? true) {
+ new KnownVersionsTableMigration(follower, 'KnownVersionsMigration', {
+ bucket,
+ table: knownVersions,
+ users: [follower, packuments.function],
+ });
+ }
+
const restager = new ReStagePackageVersion(scope, 'ReStagePackageVersion', {
description: `Manually re-stage a package version`,
environment: {
@@ -329,6 +327,7 @@ export class NpmJs implements IPackageSource {
follower,
stager,
packuments.function,
+ packuments.queue,
monitoring,
rule
);
@@ -474,36 +473,19 @@ export class NpmJs implements IPackageSource {
0
),
fillMetric(
- this.metricLaggyPackuments({ label: 'Laggy Packuments' }),
- 0
- ),
- fillMetric(
- this.metricLaggyPackumentsRecovered({
- label: 'Laggy Packuments Recovered',
- }),
- 0
- ),
- fillMetric(
- this.metricLaggyPackumentGiveUps({
- label: 'Laggy Packument Give-Ups',
+ this.metricFailedPackumentRetrievals({
+ label: 'Failed Packument Retrievals',
}),
0
),
- fillMetric(
- this.metricMissingPackuments({ label: 'Missing Packuments' }),
- 0
- ),
- fillMetric(
- this.metricMissingPackumentsRecovered({
- label: 'Missing Packuments Recovered',
- }),
- 0
- ),
- fillMetric(
- this.metricMissingPackumentGiveUps({
- label: 'Missing Packument Give-Ups',
- }),
- 0
+ ...['Laggy', 'Missing', 'Unreachable'].map((reason) =>
+ fillMetric(
+ this.metricPackumentGiveUps({
+ label: `${reason} Packument Give-Ups`,
+ dimensionsMap: { Reason: reason },
+ }),
+ 0
+ )
),
fillMetric(
this.metricMetadataFetchFailures({
@@ -544,18 +526,23 @@ export class NpmJs implements IPackageSource {
],
leftYAxis: { min: 0 },
right: [
- this.metricLaggyPackumentLag({
- label: 'Laggy Packument Lag (p90)',
- }),
+ this.metricPackumentDelay({ label: 'Packument Delay (p90)' }),
+ ],
+ leftAnnotations: [
+ {
+ color: '#ff0000',
+ label: 'Alarm',
+ value: PENDING_PACKUMENTS_ALARM_THRESHOLD,
+ },
],
rightAnnotations: [
{
color: '#ff0000',
label: 'Alarm',
- value: LAGGY_PACKUMENT_LAG_ALARM_THRESHOLD.toMilliseconds(),
+ value: PACKUMENT_DELAY_ALARM_THRESHOLD.toSeconds(),
},
],
- rightYAxis: { label: 'Milliseconds', min: 0, showUnits: false },
+ rightYAxis: { label: 'Seconds', min: 0, showUnits: false },
period: Duration.minutes(5),
}),
],
@@ -689,14 +676,17 @@ export class NpmJs implements IPackageSource {
}
/**
- * The number of requests in the packument queue, for laggy and missing
- * packuments. A package that lagged in several change entries has several
- * requests.
+ * The number of change entries for which the registry served an older
+ * packument revision than the `_changes` feed announced. The served
+ * versions are processed; the packument processor keeps re-checking for
+ * the announced revision.
+ *
+ * @deprecated no longer emitted. Use `metricFailedPackumentRetrievals` instead.
*/
public metricLaggyPackuments(opts?: MetricOptions): Metric {
return new Metric({
period: Duration.minutes(5),
- statistic: Stats.MAXIMUM,
+ statistic: Stats.SUM,
...opts,
metricName: MetricName.LAGGY_PACKUMENTS,
namespace: METRICS_NAMESPACE,
@@ -706,6 +696,8 @@ export class NpmJs implements IPackageSource {
/**
* The number of laggy packuments for which the registry caught up with the
* revision announced by the `_changes` feed.
+ *
+ * @deprecated no longer emitted. Use `metricPackumentDelay` instead.
*/
public metricLaggyPackumentsRecovered(opts?: MetricOptions): Metric {
return new Metric({
@@ -722,6 +714,8 @@ export class NpmJs implements IPackageSource {
* never served the revision announced by the `_changes` feed within the
* maximum retry age. A version announced by the feed may be missing until
* the affected package publishes again.
+ *
+ * @deprecated no longer emitted. Use `metricPackumentGiveUps` instead.
*/
public metricLaggyPackumentGiveUps(opts?: MetricOptions): Metric {
return new Metric({
@@ -736,6 +730,8 @@ export class NpmJs implements IPackageSource {
/**
* How long laggy packuments took to catch up (or until they were given up
* on), measured from when the follower first saw them.
+ *
+ * @deprecated no longer emitted. Use `metricPackumentDelay` instead.
*/
public metricLaggyPackumentLag(opts?: MetricOptions): Metric {
return new Metric({
@@ -751,6 +747,8 @@ export class NpmJs implements IPackageSource {
* The number of change entries for which the registry had no packument at
* all (HTTP 404). Usually a new package that has not replicated to the
* registry yet; the packument processor keeps re-checking for it.
+ *
+ * @deprecated no longer emitted. Use `metricFailedPackumentRetrievals` instead.
*/
public metricMissingPackuments(opts?: MetricOptions): Metric {
return new Metric({
@@ -764,6 +762,8 @@ export class NpmJs implements IPackageSource {
/**
* The number of missing packuments the registry has since served.
+ *
+ * @deprecated no longer emitted. Use `metricPackumentDelay` instead.
*/
public metricMissingPackumentsRecovered(opts?: MetricOptions): Metric {
return new Metric({
@@ -779,6 +779,8 @@ export class NpmJs implements IPackageSource {
* The number of missing packuments given up on: the registry never served a
* packument for the package within the maximum retry age. Usually an old
* change entry for a package that no longer exists.
+ *
+ * @deprecated no longer emitted. Use `metricPackumentGiveUps` instead.
*/
public metricMissingPackumentGiveUps(opts?: MetricOptions): Metric {
return new Metric({
@@ -790,6 +792,55 @@ export class NpmJs implements IPackageSource {
});
}
+ /**
+ * The number of packument checks where the registry did not serve the
+ * revision the `_changes` feed announced: it served an older one, had no
+ * packument, or could not be reached. Every check counts, so this shows
+ * registry trouble while it happens.
+ */
+ public metricFailedPackumentRetrievals(opts?: MetricOptions): Metric {
+ return new Metric({
+ period: Duration.minutes(5),
+ statistic: Stats.SUM,
+ ...opts,
+ metricName: MetricName.FAILED_PACKUMENT_RETRIEVALS,
+ namespace: METRICS_NAMESPACE,
+ });
+ }
+
+ /**
+ * The number of packument requests given up on, because the registry still
+ * had not served the announced revision after a day. A version announced by
+ * the `_changes` feed may be missing until the package publishes again.
+ *
+ * This is the total. For one reason, pass `dimensionsMap: { Reason }` with
+ * `Laggy` (an older revision), `Missing` (no packument) or `Unreachable`
+ * (the registry could not be reached), as found by the last check.
+ */
+ public metricPackumentGiveUps(opts?: MetricOptions): Metric {
+ return new Metric({
+ period: Duration.minutes(5),
+ statistic: Stats.SUM,
+ ...opts,
+ metricName: MetricName.PACKUMENT_GIVE_UPS,
+ namespace: METRICS_NAMESPACE,
+ });
+ }
+
+ /**
+ * For packuments the registry served only after earlier checks failed: how
+ * long that took, in seconds, from when the follower read the change entry.
+ */
+ public metricPackumentDelay(opts?: MetricOptions): Metric {
+ return new Metric({
+ period: Duration.minutes(5),
+ statistic: Stats.p(90),
+ ...opts,
+ metricName: MetricName.PACKUMENT_DELAY,
+ namespace: METRICS_NAMESPACE,
+ });
+ }
+
public metricNpmJsChangeAge(opts?: MetricOptions): Metric {
return new Metric({
period: Duration.minutes(1),
@@ -872,6 +923,7 @@ export class NpmJs implements IPackageSource {
follower: NpmJsFollower,
stager: StageAndNotify,
packumentProcessor: IFunction,
+ packumentQueue: IQueue,
monitoring: IMonitoring,
schedule: Rule
) {
@@ -989,47 +1041,53 @@ export class NpmJs implements IPackageSource {
lateChangeLagAlarm
);
- const missingPackumentsAlarm = this.metricMissingPackuments({
- period: Duration.hours(3),
- }).createAlarm(scope, 'NpmJs/Follower/MissingPackumentsHigh', {
- alarmName: `${scope.node.path}/NpmJs/Follower/MissingPackumentsHigh`,
- alarmDescription: [
- 'The npm registry had no packument for an unusually high number of packages announced by',
- 'the CouchDB changes feed. This usually means the registry has an outage or is far behind',
- 'the feed. The packument processor keeps re-checking these packages.',
- '',
- `Runbook: ${RUNBOOK_URL}`,
- ].join('\n'),
- comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
- evaluationPeriods: 1,
- threshold: MISSING_PACKUMENTS_ALARM_THRESHOLD,
- treatMissingData: TreatMissingData.NOT_BREACHING,
- });
+ const pendingPackumentsAlarm = packumentQueue
+ .metricApproximateNumberOfMessagesNotVisible({
+ period: Duration.hours(1),
+ // Each hour's lowest count, so a burst of new requests being processed
+ // does not count.
+ statistic: Stats.MINIMUM,
+ })
+ .createAlarm(scope, 'NpmJs/PackumentProcessor/PendingPackumentsHigh', {
+ alarmName: `${scope.node.path}/NpmJs/PackumentProcessor/PendingPackumentsHigh`,
+ alarmDescription: [
+ 'An unusually high number of packages wait for the npm registry to serve the revision the',
+ 'CouchDB changes feed announced, for 3 hours. This usually means the registry has an outage',
+ 'or is far behind the feed. The packument processor keeps re-checking these packages.',
+ '',
+ `Runbook: ${RUNBOOK_URL}`,
+ ].join('\n'),
+ comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
+ evaluationPeriods: 3,
+ threshold: PENDING_PACKUMENTS_ALARM_THRESHOLD,
+ treatMissingData: TreatMissingData.NOT_BREACHING,
+ });
monitoring.addLowSeverityAlarm(
- 'NpmJs/Follower Missing Packuments High',
- missingPackumentsAlarm
+ 'NpmJs/PackumentProcessor Pending Packuments High',
+ pendingPackumentsAlarm
);
- const laggyPackumentLagAlarm = this.metricLaggyPackumentLag({
+ // The id and name stay "LaggyPackumentLag", so existing alarm overrides
+ // keep working.
+ const packumentDelayAlarm = this.metricPackumentDelay({
period: Duration.hours(3),
- statistic: Stats.p(90),
}).createAlarm(scope, 'NpmJs/PackumentProcessor/LaggyPackumentLagHigh', {
alarmName: `${scope.node.path}/NpmJs/PackumentProcessor/LaggyPackumentLagHigh`,
alarmDescription: [
- 'Laggy packuments take unusually long to catch up: the npm registry serves older revisions',
- 'than the CouchDB changes feed announced, for hours. This usually means the registry has an',
- 'outage or is far behind the feed. The packument processor keeps re-checking these packages.',
+ 'The npm registry takes unusually long to serve the revisions the CouchDB changes feed',
+ 'announced: for hours. This usually means the registry has an outage or is far behind the',
+ 'feed. The packument processor keeps re-checking these packages.',
'',
`Runbook: ${RUNBOOK_URL}`,
].join('\n'),
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
evaluationPeriods: 1,
- threshold: LAGGY_PACKUMENT_LAG_ALARM_THRESHOLD.toMilliseconds(),
+ threshold: PACKUMENT_DELAY_ALARM_THRESHOLD.toSeconds(),
treatMissingData: TreatMissingData.NOT_BREACHING,
});
monitoring.addLowSeverityAlarm(
'NpmJs/PackumentProcessor Laggy Packument Lag High',
- laggyPackumentLagAlarm
+ packumentDelayAlarm
);
const packumentProcessorFailuresAlarm = packumentProcessor
@@ -1037,8 +1095,8 @@ export class NpmJs implements IPackageSource {
.createAlarm(scope, 'NpmJs/PackumentProcessor/Failures', {
alarmName: `${scope.node.path}/NpmJs/PackumentProcessor/Failures`,
alarmDescription: [
- 'The packument processor function is failing (errors or time-outs). Requests in the',
- 'packument queue use up their attempts while it fails, and may be given up on early.',
+ 'The packument processor function is failing (errors or time-outs). Requests that keep',
+ 'failing it move to the packument dead-letter queue.',
'',
`Link to the lambda function: ${lambdaFunctionUrl(
packumentProcessor
diff --git a/src/package-sources/npmjs/constants.lambda-shared.ts b/src/package-sources/npmjs/constants.lambda-shared.ts
index 7d8972c83..fe1f0da19 100644
--- a/src/package-sources/npmjs/constants.lambda-shared.ts
+++ b/src/package-sources/npmjs/constants.lambda-shared.ts
@@ -39,54 +39,62 @@ export const enum MetricName {
*/
METADATA_FETCH_FAILURES = 'MetadataFetchFailures',
- /**
- * The number of packages for which the registry packument is still behind
- * the revision announced by the `_changes` feed ("laggy packuments"). The
- * versions served so far have been processed; the follower keeps re-checking
- * for the announced revision.
- */
+ /** No longer emitted. */
LAGGY_PACKUMENTS = 'LaggyPackuments',
- /**
- * Number of laggy packuments for which the registry caught up with the
- * revision announced by the `_changes` feed.
- */
+ /** No longer emitted. */
LAGGY_PACKUMENTS_RECOVERED = 'LaggyPackumentsRecovered',
- /**
- * Number of laggy packuments given up on: the registry never
- * served the revision announced by the `_changes` feed within the maximum
- * retry age. Any versions the registry did serve have been processed, but a
- * version announced by the feed may be missing until the package publishes
- * again.
- */
+ /** No longer emitted, see `PACKUMENT_GIVE_UPS`. */
LAGGY_PACKUMENT_GIVE_UPS = 'LaggyPackumentGiveUps',
- /**
- * How long a laggy packument took to catch up (or until it was given up
- * on), measured from when the follower first saw it.
- */
+ /** No longer emitted, see `PACKUMENT_DELAY`. */
LAGGY_PACKUMENT_LAG = 'LaggyPackumentLag',
+ /** No longer emitted. */
+ MISSING_PACKUMENTS = 'MissingPackuments',
+
+ /** No longer emitted. */
+ MISSING_PACKUMENTS_RECOVERED = 'MissingPackumentsRecovered',
+
+ /** No longer emitted, see `PACKUMENT_GIVE_UPS`. */
+ MISSING_PACKUMENT_GIVE_UPS = 'MissingPackumentGiveUps',
+
/**
- * Number of change entries for which the registry had no packument at all
- * (HTTP 404) when the follower processed them. Usually a new package that
- * has not replicated to the registry yet; they are re-checked like laggy
- * packuments.
+ * Number of packument checks where the registry did not serve the announced
+ * revision: it served an older one, had no packument, or could not be
+ * reached. Counted on every check, so it shows registry trouble while it
+ * happens.
*/
- MISSING_PACKUMENTS = 'MissingPackuments',
+ FAILED_PACKUMENT_RETRIEVALS = 'FailedPackumentRetrievals',
/**
- * Number of missing packuments the registry has since served.
+ * Number of packument requests given up on, because the registry still had
+ * not served the announced revision after a day. Emitted with a `Reason`
+ * dimension (see `PackumentGiveUpReason`), and without it for the total. A
+ * version announced by the changes feed may be missing until the package
+ * publishes again.
*/
- MISSING_PACKUMENTS_RECOVERED = 'MissingPackumentsRecovered',
+ PACKUMENT_GIVE_UPS = 'PackumentGiveUps',
/**
- * Number of missing packuments given up on: the registry never served a
- * packument for the package within the maximum retry age. Usually an old
- * change entry for a deleted package.
+ * For packuments the registry served only after earlier checks failed: how
+ * long that took, in seconds, from when the follower read the change entry.
*/
- MISSING_PACKUMENT_GIVE_UPS = 'MissingPackumentGiveUps',
+ PACKUMENT_DELAY = 'PackumentDelay',
+}
+
+/**
+ * Why a packument request was given up on: the value of the `Reason`
+ * dimension of the `PackumentGiveUps` metric. Decided by the last check.
+ */
+export const enum PackumentGiveUpReason {
+ /** The registry served an older revision than announced. */
+ LAGGY = 'Laggy',
+ /** The registry had no packument for the package (HTTP 404). */
+ MISSING = 'Missing',
+ /** The registry could not be reached. */
+ UNREACHABLE = 'Unreachable',
}
export const enum S3KeyPrefix {
@@ -170,18 +178,6 @@ export const NPM_REPLICA_REGISTRY_URL = 'https://replicate.npmjs.com/';
*/
export const ENV_PACKUMENT_QUEUE_URL = 'PACKUMENT_QUEUE_URL';
-/**
- * The environment variable holding the ARN of the packument dead-letter queue.
- * The packument processor reads both queues, and tells them apart by this.
- */
-export const ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN =
- 'PACKUMENT_DEAD_LETTER_QUEUE_ARN';
-
-/**
- * How long a new packument request waits before it is first processed.
- */
-export const PACKUMENT_INITIAL_DELAY_SECONDS = 5 * 60; // 5 minutes
-
/**
* The shortest and longest wait before the next attempt. In between, a request
* waits as long as it is already old, so waits double with each attempt. SQS
@@ -196,9 +192,17 @@ export const PACKUMENT_MAX_RETRY_DELAY_SECONDS = 6 * 60 * 60; // 6 hours
*/
export const PACKUMENT_RETRY_JITTER = 0.2;
+/**
+ * How old a request gets before it is given up on, if its last check still
+ * did not find the announced revision.
+ */
+export const PACKUMENT_MAX_AGE_MS = 24 * 60 * 60 * 1_000; // 24 hours
+
/**
* The number of attempts before a request moves to the dead-letter queue (the
- * queue's `maxReceiveCount`). With the waits above, that is after about 29
- * hours.
+ * queue's `maxReceiveCount`). Only a backstop for requests that keep failing
+ * the processor: with the waits above, a request passes `PACKUMENT_MAX_AGE_MS`
+ * after about 12 attempts, and the rest leaves room for attempts that timed
+ * out.
*/
-export const PACKUMENT_MAX_ATTEMPTS = 10;
+export const PACKUMENT_MAX_ATTEMPTS = 20;
diff --git a/src/package-sources/npmjs/couch-changes.lambda-shared.ts b/src/package-sources/npmjs/couch-changes.lambda-shared.ts
index 235e5d658..38200cdb3 100644
--- a/src/package-sources/npmjs/couch-changes.lambda-shared.ts
+++ b/src/package-sources/npmjs/couch-changes.lambda-shared.ts
@@ -107,111 +107,6 @@ export class CouchChanges extends EventEmitter {
}
}
- /**
- * Fetches the registry metadata for each of the provided change entries and
- * attaches it to the entry. Entries for deleted packages are dropped.
- *
- * The registry is a separate system from the changes feed and can serve a
- * packument revision older than the revision the feed announced (a "laggy
- * packument"). Such entries are returned with `laggy: true`: the caller
- * should process the versions that were served, and separately track the
- * expectation that the announced revision will eventually appear.
- *
- * The registry can also have no packument at all yet (HTTP 404), usually
- * because a new package has not replicated to it yet. Such entries are
- * returned in `missing`, and should be tracked the same way.
- */
- public async attachAllMetadata(
- changes: readonly DatabaseChange[]
- ): Promise {
- const ok = new Array();
- const missing = new Array();
- const failedSeqs = new Array();
- await Promise.all(
- changes.map(async (change) => {
- try {
- const outcome = await this.attachMetadata(change);
- if (outcome?.attached) {
- ok.push(outcome.attached);
- } else if (outcome?.missing) {
- missing.push(outcome.missing);
- }
- } catch (error) {
- // One unreachable packument must not fail the whole batch. The
- // entry is reported as failed so the caller does not record a
- // receipt for it; a later scan retries it.
- console.error(
- `Failed to fetch metadata for ${change.id}, a later scan will retry it: ${error}`
- );
- const seq = Number(change.seq);
- if (!isNaN(seq)) {
- failedSeqs.push(seq);
- }
- }
- })
- );
- return { ok, missing, failedSeqs };
- }
-
- private async attachMetadata(
- change: DatabaseChange
- ): Promise<
- | { attached: AttachedChange; missing?: undefined }
- | { attached?: undefined; missing: MissingPackument }
- | undefined
- > {
- // Filter out deleted packages or null ids
- if (change.deleted || !change.id) {
- console.log(`Skipping ${change.id}: deleted or null id`);
- return undefined;
- }
-
- // note: this function should not throw validation errors as
- // it may cause a poison pill - whereby a single corrupt package will
- // fail the entire lambda execution and prevent us from ingesting any package.
- // instead, log the violation and return undefined.
- const metadataUrl = new URL(change.id, NPM_REGISTRY_URL);
- console.log(`Fetching metadata for ${change.id}: ${metadataUrl}`);
- let meta;
- try {
- meta = await this.https('get', metadataUrl);
- } catch (e: any) {
- if (e.message?.includes('HTTP 404')) {
- console.log(
- `${change.id}: the registry has no packument for it yet (HTTP 404)`
- );
- return {
- missing: { change, announcedRev: getMaxSequentialRevision(change) },
- };
- }
- throw e;
- }
-
- if (!meta) {
- // can happen if a package was removed from npm
- console.log(`Skipping ${change.id} because no metadata found`);
- return undefined;
- }
- if (!meta._rev) {
- // can happen if a package was removed from npm
- console.log(`Skipping ${change.id} because no _rev found in metadata`);
- return undefined;
- }
-
- const announcedRev = getMaxSequentialRevision(change);
- const servedRev = parseSequentialRevision(meta._rev as string);
- change.doc = meta; // add metadata to the change object
-
- return {
- attached: {
- change,
- announcedRev,
- servedRev,
- laggy: servedRev < announcedRev,
- },
- };
- }
-
/**
* Makes an HTTPs request using the provided method, url, and optionally payload. This function
* properly handles input that is received with `Content-Type: gzip` and automatically retries
@@ -395,68 +290,6 @@ export interface DatabaseChanges {
/**
* The result of attaching registry metadata to a batch of change entries.
*/
-export interface AttachedMetadata {
- /**
- * The change entries whose metadata could be fetched.
- */
- readonly ok: AttachedChange[];
-
- /**
- * The change entries for which the registry has no packument (yet).
- */
- readonly missing: MissingPackument[];
-
- /**
- * The sequence numbers of change entries whose metadata fetch failed. No
- * receipt must be recorded for these, so that a later scan retries them.
- */
- readonly failedSeqs: number[];
-}
-
-/**
- * A change entry for which the registry has no packument (HTTP 404). Usually
- * a new package that has not replicated to the registry yet; rarely an old
- * change entry for a package that no longer exists.
- */
-export interface MissingPackument {
- /** The change entry. */
- readonly change: DatabaseChange;
-
- /**
- * The highest sequential revision announced by the changes feed for this
- * entry.
- */
- readonly announcedRev: number;
-}
-
-/**
- * A change entry with its registry metadata attached.
- */
-export interface AttachedChange {
- /**
- * The change entry, with the packument attached as `doc`.
- */
- readonly change: DatabaseChange;
-
- /**
- * The highest sequential revision announced by the changes feed for this
- * entry.
- */
- readonly announcedRev: number;
-
- /**
- * The sequential revision of the packument the registry actually served.
- */
- readonly servedRev: number;
-
- /**
- * Whether the served packument is behind the announced revision (a "laggy
- * packument"). The served versions can (and should) still be processed, but
- * the announced revision has not been observed yet.
- */
- readonly laggy: boolean;
-}
-
export interface DatabaseChange {
/**
* The set of revisions to the object that were resolved as part of this
diff --git a/src/package-sources/npmjs/known-versions-table-migration.ts b/src/package-sources/npmjs/known-versions-table-migration.ts
index 9f144fca0..00626f6a9 100644
--- a/src/package-sources/npmjs/known-versions-table-migration.ts
+++ b/src/package-sources/npmjs/known-versions-table-migration.ts
@@ -18,8 +18,11 @@ export interface KnownVersionsTableMigrationProps {
/** The table to copy the known versions to. */
readonly table: ITableV2;
- /** The follower function, which is only updated once the copy completed. */
- readonly follower: Function;
+ /**
+ * The functions that use the table. They are only updated once the copy
+ * completed.
+ */
+ readonly users: Function[];
}
/**
@@ -27,11 +30,11 @@ export interface KnownVersionsTableMigrationProps {
* to the known versions table, when the table is created. The copy runs in two
* passes:
*
- * - Before the follower function is updated, so the new follower code never
- * runs against an empty table. If this copy fails, the deployment fails and
- * rolls back.
- * - After the follower function is updated, to pick up the versions the old
- * follower code recorded in the file while the first copy ran.
+ * - Before the functions that use the table are updated, so their new code
+ * never runs against an empty table. If this copy fails, the deployment
+ * fails and rolls back.
+ * - After they are updated, to pick up the versions the old follower code
+ * recorded in the file while the first copy ran.
*
* Copying is idempotent, so the second pass only adds what is missing.
*/
@@ -44,7 +47,7 @@ export class KnownVersionsTableMigration extends Construct {
super(scope, id);
const handler = new KnownVersionsMigration(this, 'Function', {
- description: `[${props.follower.node.path}] Copies the known versions from the staging bucket to the known versions table`,
+ description: `[${this.node.path}] Copies the known versions from the staging bucket to the known versions table`,
environment: {
BUCKET_NAME: props.bucket.bucketName,
[ENV_KNOWN_VERSIONS_TABLE_NAME]: props.table.tableName,
@@ -57,10 +60,12 @@ export class KnownVersionsTableMigration extends Construct {
props.bucket.grantRead(handler, MARKER_FILE_NAME);
props.table.grantWriteData(handler);
- // The function resource only, not the follower's whole scope (which may
- // contain this construct).
- const followerFunction = props.follower.node.defaultChild as CfnFunction;
+ // The function resources only, not their whole scopes (which may contain
+ // this construct).
+ const users = props.users.map((fn) => fn.node.defaultChild as CfnFunction);
+ // The ids stay "Follower" for existing deployments: a new id would run the
+ // migration again.
new Trigger(this, 'BeforeFollowerUpdate', {
handler,
invocationType: InvocationType.REQUEST_RESPONSE,
@@ -70,7 +75,7 @@ export class KnownVersionsTableMigration extends Construct {
// Only when the trigger is created, not on later updates.
executeOnHandlerChange: false,
executeAfter: [props.table],
- executeBefore: [followerFunction],
+ executeBefore: users,
});
new Trigger(this, 'AfterFollowerUpdate', {
@@ -78,7 +83,7 @@ export class KnownVersionsTableMigration extends Construct {
// Nothing waits for this one; a failure is retried by Lambda.
invocationType: InvocationType.EVENT,
executeOnHandlerChange: false,
- executeAfter: [followerFunction],
+ executeAfter: users,
});
}
}
diff --git a/src/package-sources/npmjs/npm-js-follower.lambda.ts b/src/package-sources/npmjs/npm-js-follower.lambda.ts
index a3d025078..fb4ac2984 100644
--- a/src/package-sources/npmjs/npm-js-follower.lambda.ts
+++ b/src/package-sources/npmjs/npm-js-follower.lambda.ts
@@ -12,7 +12,6 @@ import {
MetricName,
MARKER_FILE_NAME,
METRICS_NAMESPACE,
- ENV_KNOWN_VERSIONS_TABLE_NAME,
FOLLOWER_STATE_FILE_NAME,
SCAN_WINDOW_MS,
STATE_RETENTION_MS,
@@ -21,39 +20,20 @@ import {
} from './constants.lambda-shared';
import {
CouchChanges,
- DatabaseChange,
DatabaseChanges,
+ getMaxSequentialRevision,
} from './couch-changes.lambda-shared';
import { FollowerState } from './follower-state.lambda-shared';
-import { KnownVersions } from './known-versions.lambda-shared';
-import {
- PackumentProcessingContext,
- PackumentRequest,
- PackumentRequestReason,
- processPackuments,
-} from './packument-processing.lambda-shared';
-import {
- enqueuePackumentRequests,
- queuedPackumentRequests,
-} from './packument-queue.lambda-shared';
+import { PackumentRequest } from './packument-processing.lambda-shared';
+import { enqueuePackumentRequests } from './packument-queue.lambda-shared';
import {
loadContentFromS3,
MarkerFileSchema,
putObject,
} from './staging-bucket.lambda-shared';
-import { DenyListClient } from '../../backend/deny-list/client.lambda-shared';
-import { LicenseListClient } from '../../backend/license-list/client.lambda-shared';
import { compressContent } from '../../backend/shared/compress-content.lambda-shared';
import { requireEnv } from '../../backend/shared/env.lambda-shared';
-/**
- * The release date of `aws-cdk@0.8.0`. Anything earlier than this basically is
- * not a relevant package, as it cannot possibly be a constructs-based package.
- * This is used to fast-forward over boring stuff when the follower state is
- * seeded far in the past.
- */
-const DAWN_OF_CONSTRUCTS = new Date('2018-07-31T13:43:04.615Z');
-
/**
* The page size used when scanning the `_changes` feed. Receipts discard
* already-received entries before any packument is fetched, so scans can
@@ -94,13 +74,9 @@ captureHTTPsGlobal(require('http'));
* window instead).
* 2. Each scan reads the window ascending from the floor. Receipts make
* re-reads of already-covered ranges nearly free.
- * 3. For each new entry, the packument is fetched from the registry and every
- * version it contains is processed (deny list, license, and known-versions
- * checks apply). If the packument is behind the revision announced by the
- * feed (a "laggy packument"), the served versions are still processed, and
- * a request to check the package again is sent to the packument queue,
- * where it is retried until the announced revision appears or it is given
- * up on.
+ * 3. Each new entry is sent to the packument queue, where the packument
+ * processor fetches the package from the registry and processes it. The
+ * follower itself never fetches packuments.
*
* npm registry API docs: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md
*
@@ -111,15 +87,6 @@ export async function handler(event: ScheduledEvent, context: Context) {
const stagingBucket = requireEnv('BUCKET_NAME');
const queueUrl = requireEnv(ENV_PACKUMENT_QUEUE_URL);
- const knownVersions = new KnownVersions(
- requireEnv(ENV_KNOWN_VERSIONS_TABLE_NAME)
- );
- const processing: PackumentProcessingContext = {
- stagingFunction: requireEnv('FUNCTION_NAME'),
- denyList: await DenyListClient.newClient(),
- licenseList: await LicenseListClient.newClient(),
- knownVersions,
- };
const npm = new CouchChanges(NPM_REPLICA_REGISTRY_URL, 'registry/_changes');
@@ -143,24 +110,12 @@ export async function handler(event: ScheduledEvent, context: Context) {
// every processed chunk (see PersistState), so even a run that is hard
// killed by the Lambda timeout keeps its completed work.
const persist: PersistState = () =>
- persistProgress(context, stagingBucket, state, knownVersions);
- await runScan(context, npm, state, head, processing, queueUrl, persist);
-
- // Requests waiting in the packument queue, including those this run sent.
- const laggyPackuments = await queuedPackumentRequests(queueUrl);
- await metricScope((metrics) => async () => {
- metrics.setDimensions({});
- metrics.putMetric(
- MetricName.LAGGY_PACKUMENTS,
- laggyPackuments,
- Unit.Count
- );
- })();
+ saveFollowerState(context, stagingBucket, state);
+ await runScan(context, npm, state, head, queueUrl, persist);
} finally {
- // Persist the state even when a scan failed part-way: receipts, interim
- // checkpoints, and staged known versions represent completed work that
- // the next run should not redo.
- await persistProgress(context, stagingBucket, state, knownVersions);
+ // Persist the state even when a scan failed part-way: receipts and
+ // interim checkpoints are completed work the next run should not redo.
+ await saveFollowerState(context, stagingBucket, state);
}
console.log('All done here, we have success!');
@@ -170,8 +125,7 @@ export async function handler(event: ScheduledEvent, context: Context) {
//#region Scan
/**
- * A callback persisting the follower state (and optionally the known
- * versions) to S3. Called after every processed chunk, so that progress is
+ * A callback persisting the follower state to S3. Called after every processed chunk, so that progress is
* durable even when the Lambda times out mid-scan: a timeout is a hard kill,
* and anything not persisted would be redone by the next run. Without this, a
* backlog too large for a single execution would never complete (every run
@@ -179,26 +133,6 @@ export async function handler(event: ScheduledEvent, context: Context) {
*/
type PersistState = () => Promise;
-/**
- * Persists the known versions recorded since the last call, then the follower
- * state. Known versions go first: if saving the state fails, the next run
- * redoes the work, and the known versions prevent it from staging the same
- * versions again. The reverse order could record receipts for entries whose
- * staged versions were never recorded as known.
- */
-async function persistProgress(
- context: Context,
- stagingBucket: string,
- state: FollowerState,
- knownVersions: KnownVersions
-): Promise {
- if (knownVersions.pendingCount > 0) {
- console.log(`Recording ${knownVersions.pendingCount} known version(s)`);
- await knownVersions.flush();
- }
- await saveFollowerState(context, stagingBucket, state);
-}
-
/**
* Re-reads the trailing window of the feed and processes every change entry
* for which no receipt exists. A checkpoint is only recorded when the scan
@@ -212,10 +146,9 @@ async function runScan(
npm: CouchChanges,
state: FollowerState,
head: number,
- processing: PackumentProcessingContext,
queueUrl: string,
persist: PersistState
-): Promise {
+): Promise {
const now = Date.now();
const deep = state.deepScanDue(now);
const windowMs = deep ? STATE_RETENTION_MS : SCAN_WINDOW_MS;
@@ -223,7 +156,7 @@ async function runScan(
if (floor == null) {
// Cannot happen after seeding, but guards the type.
console.warn('No checkpoint history; skipping scan');
- return 0;
+ return;
}
// Entries discovered at or below this position were inserted into the feed
// behind a position we had already read past.
@@ -235,7 +168,6 @@ async function runScan(
}scan of (${floor}, ${head}] (late boundary: ${lateBoundary})`
);
- let staged = 0;
let completed = false;
let maxSeqSeen = head;
@@ -261,15 +193,12 @@ async function runScan(
batch,
metrics,
context,
- npm,
state,
lateBoundary,
head,
- processing,
queueUrl,
persist
);
- staged += outcome.staged;
if (!outcome.fullyProcessed) {
// The batch was only partially processed (time budget): the
// unprocessed entries carry no receipt, so the next run picks them
@@ -304,58 +233,52 @@ async function runScan(
'Scan ran out of time; it will resume on the next run (no checkpoint recorded)'
);
}
- return staged;
}
/**
- * The maximum number of packument fetches per processing chunk. Chunking
- * bounds how much work is lost when the Lambda is killed mid-chunk, and lets
- * the time budget be re-checked between chunks: during a catch-up, a single
- * page can contain thousands of unreceipted entries, far more than fit into
- * one execution.
+ * The maximum number of change entries per chunk. The follower persists its
+ * state after every chunk, and re-checks its time budget in between.
*/
-const METADATA_CHUNK_SIZE = 1_000;
+const CHUNK_SIZE = 1_000;
/**
* Processes one page of change entries: discards everything we already have a
- * receipt for, then works through the remainder in chunks. Each chunk fetches
- * packuments, stages new relevant package versions, records laggy packument
- * expectations and receipts, and persists the state - so completed chunks
+ * receipt for, then works through the remainder in chunks. Each chunk is sent
+ * to the packument queue, receipted, and persisted, so completed chunks
* survive a timeout. Processing stops between chunks when the time budget is
* exhausted; unprocessed entries carry no receipt and are picked up by the
* next run.
*
- * @returns the number of package versions sent for staging, and whether all
- * entries of the page were processed.
+ * @returns whether all entries of the page were processed.
*/
async function processBatch(
batch: DatabaseChanges,
metrics: MetricsLogger,
context: Context,
- npm: CouchChanges,
state: FollowerState,
lateBoundary: number,
head: number,
- processing: PackumentProcessingContext,
queueUrl: string,
persist: PersistState
-): Promise<{ staged: number; fullyProcessed: boolean }> {
+): Promise<{ fullyProcessed: boolean }> {
const startTime = Date.now();
- let staged = 0;
let fullyProcessed = true;
try {
// Entries for deleted packages are ignored, as if they were not in the
// feed: there is nothing to process, and no receipt is recorded.
const fresh = batch.results.filter(
(change) =>
- !change.deleted && change.seq != null && !state.has(Number(change.seq))
+ !change.deleted &&
+ change.id &&
+ change.seq != null &&
+ !state.has(Number(change.seq))
);
console.log(
`Received ${batch.totalCount} change entr(ies), ${fresh.length} without a receipt`
);
metrics.putMetric(MetricName.CHANGE_COUNT, fresh.length, Unit.Count);
- for (let offset = 0; offset < fresh.length; offset += METADATA_CHUNK_SIZE) {
+ for (let offset = 0; offset < fresh.length; offset += CHUNK_SIZE) {
if (
offset > 0 &&
context.getRemainingTimeInMillis() < SCAN_TIME_BUDGET_MS
@@ -366,7 +289,7 @@ async function processBatch(
fullyProcessed = false;
break;
}
- const chunk = fresh.slice(offset, offset + METADATA_CHUNK_SIZE);
+ const chunk = fresh.slice(offset, offset + CHUNK_SIZE);
// Entries below the late boundary were inserted into the feed behind a
// position a completed scan had already read past.
@@ -386,101 +309,22 @@ async function processBatch(
);
}
- const {
- ok: attached,
- missing,
- failedSeqs,
- } = await npm.attachAllMetadata(chunk);
- metrics.putMetric(
- MetricName.METADATA_FETCH_FAILURES,
- failedSeqs.length,
- Unit.Count
- );
-
- // The most recent "modified" timestamp observed in the chunk.
- let lastModified: Date | undefined;
- // Emit npm.js replication lag
- for (const { change } of attached) {
- const doc = change.doc as { time?: { modified?: string } } | undefined;
- if (doc?.time?.modified) {
- const modified = new Date(doc.time.modified);
- metrics.putMetric(
- MetricName.NPMJS_CHANGE_AGE,
- startTime - modified.getTime(),
- Unit.Milliseconds
- );
- if (lastModified == null || lastModified < modified) {
- lastModified = modified;
- }
- }
- }
-
- let chunkStaged = 0;
- if (lastModified && lastModified < DAWN_OF_CONSTRUCTS) {
- console.log(
- `Skipping chunk as the latest modification is ${lastModified}, which is pre-Constructs`
- );
- } else {
- chunkStaged = await processPackuments(
- attached.map((a) => a.change),
- metrics,
- processing
- );
- staged += chunkStaged;
-
- // Laggy packuments: the registry served an older revision than the
- // feed announced (the versions we did get were processed above), or
- // no packument at all yet. The packument queue checks the package
- // again until the announced revision appears. This happens before the
- // receipts are recorded, so a failure here makes the next run process
- // the chunk again.
- const laggy = attached.filter((a) => a.laggy);
- for (const { change, servedRev, announcedRev } of laggy) {
- console.log(
- `${change.id}: registry packument rev ${servedRev} is behind announced rev ${announcedRev}, sending it to the packument queue`
- );
- }
- for (const { change } of missing) {
- console.log(
- `${change.id}: the registry has no packument for it yet, sending it to the packument queue`
- );
- }
- metrics.putMetric(
- MetricName.MISSING_PACKUMENTS,
- missing.length,
- Unit.Count
- );
- const now = Date.now();
- const request = (
- change: DatabaseChange,
- expectedRev: number,
- reason: PackumentRequestReason
- ): PackumentRequest => ({
- name: change.id,
- expectedRev,
- seq: isNaN(Number(change.seq)) ? undefined : Number(change.seq),
- firstSeen: now,
- reason,
- });
- await enqueuePackumentRequests(queueUrl, [
- ...laggy.map(({ change, announcedRev }) =>
- request(change, announcedRev, 'laggy')
- ),
- ...missing.map(({ change, announcedRev }) =>
- request(change, announcedRev, 'missing')
- ),
- ]);
- }
-
- // Record a receipt for every entry of the chunk, except those whose
- // metadata fetch failed (a later scan retries them). Then persist, so a
- // timeout cannot undo this chunk.
- const failed = new Set(failedSeqs);
- state.addSeqs(
- chunk
- .map((change) => Number(change.seq))
- .filter((seq) => !isNaN(seq) && !failed.has(seq))
+ // The packument processor fetches and processes each package. Receipts
+ // are only recorded once the requests are sent, so a failure here makes
+ // the next run send the chunk again.
+ const now = Date.now();
+ await enqueuePackumentRequests(
+ queueUrl,
+ chunk.map(
+ (change): PackumentRequest => ({
+ name: change.id,
+ expectedRev: getMaxSequentialRevision(change),
+ seq: Number(change.seq),
+ firstSeen: now,
+ })
+ )
);
+ state.addSeqs(chunk.map((change) => Number(change.seq)));
await persist();
}
} finally {
@@ -496,7 +340,7 @@ async function processBatch(
Unit.Milliseconds
);
}
- return { staged, fullyProcessed };
+ return { fullyProcessed };
}
//#endregion
diff --git a/src/package-sources/npmjs/packument-processing.lambda-shared.ts b/src/package-sources/npmjs/packument-processing.lambda-shared.ts
index 5fc54f0de..acdcddc61 100644
--- a/src/package-sources/npmjs/packument-processing.lambda-shared.ts
+++ b/src/package-sources/npmjs/packument-processing.lambda-shared.ts
@@ -14,6 +14,13 @@ import { LAMBDA_CLIENT } from '../../backend/shared/aws.lambda-shared';
// eslint-disable-next-line @typescript-eslint/no-require-imports
const normalizeNPMMetadata = require('normalize-registry-metadata');
+/**
+ * The release date of `aws-cdk@0.8.0`. A package last modified before this
+ * cannot be a constructs-based package. Skipping these speeds up a backfill
+ * from the beginning of the feed.
+ */
+const DAWN_OF_CONSTRUCTS = new Date('2018-07-31T13:43:04.615Z');
+
const CONSTRUCT_KEYWORDS: ReadonlySet = new Set([
'cdk',
'aws-cdk',
@@ -49,8 +56,18 @@ export async function processPackuments(
metrics: MetricsLogger,
context: PackumentProcessingContext
): Promise {
+ const recent = changes.filter((change) => {
+ const modified = modifiedOf(change.doc);
+ if (modified != null && modified < DAWN_OF_CONSTRUCTS) {
+ console.log(
+ `Skipping ${change.id}: last modified ${modified.toISOString()}, before constructs existed`
+ );
+ return false;
+ }
+ return true;
+ });
const versionInfos = await getRelevantVersionInfos(
- changes as unknown as readonly Change[],
+ recent as unknown as readonly Change[],
metrics,
context.denyList,
context.licenseList,
@@ -85,18 +102,8 @@ export interface PackumentRequest {
readonly seq?: number;
/** When the request was first made (epoch milliseconds). */
readonly firstSeen: number;
- /**
- * Why the package is checked again: the registry served an older revision
- * than announced (`laggy`), or no packument at all (`missing`).
- *
- * @default 'laggy'
- */
- readonly reason?: PackumentRequestReason;
}
-/** Why a package is checked again. */
-export type PackumentRequestReason = 'laggy' | 'missing';
-
/** The outcome of `checkPackument`. */
export type PackumentCheckResult =
/** The registry serves the expected revision (or a newer one). */
@@ -106,20 +113,31 @@ export type PackumentCheckResult =
/** The registry has no packument for the package (HTTP 404). */
| 'missing';
+/** What `checkPackument` found. */
+export interface PackumentCheck {
+ readonly result: PackumentCheckResult;
+ /** The sequential revision the registry served, if any. */
+ readonly servedRev?: number;
+ /** When the served packument was last modified, if known. */
+ readonly modified?: Date;
+}
+
/**
* Fetches the packument a request is about from the registry, processes the
* versions it contains (whatever revision it is at), and reports whether the
* registry has caught up with the expected revision.
+ *
+ * @throws if the registry could not be reached (other than HTTP 404).
*/
export async function checkPackument(
npm: CouchChanges,
request: PackumentRequest,
metrics: MetricsLogger,
context: PackumentProcessingContext
-): Promise {
+): Promise {
const doc = await npm.getPackageDoc(request.name);
if (doc == null || doc._rev == null) {
- return 'missing';
+ return { result: 'missing' };
}
const change: DatabaseChange = {
changes: [{ rev: doc._rev as string }],
@@ -129,9 +147,18 @@ export async function checkPackument(
doc,
};
await processPackuments([change], metrics, context);
- return parseSequentialRevision(doc._rev as string) >= request.expectedRev
- ? 'caught-up'
- : 'laggy';
+ const servedRev = parseSequentialRevision(doc._rev as string);
+ return {
+ result: servedRev >= request.expectedRev ? 'caught-up' : 'laggy',
+ servedRev,
+ modified: modifiedOf(doc),
+ };
+}
+
+function modifiedOf(doc: unknown): Date | undefined {
+ const modified = (doc as { time?: { modified?: string } } | undefined)?.time
+ ?.modified;
+ return modified ? new Date(modified) : undefined;
}
/**
diff --git a/src/package-sources/npmjs/packument-processor.lambda.ts b/src/package-sources/npmjs/packument-processor.lambda.ts
index df9026539..c09f12cd4 100644
--- a/src/package-sources/npmjs/packument-processor.lambda.ts
+++ b/src/package-sources/npmjs/packument-processor.lambda.ts
@@ -13,19 +13,18 @@ import type {
import { captureHTTPsGlobal } from 'aws-xray-sdk-core';
import {
ENV_KNOWN_VERSIONS_TABLE_NAME,
- ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN,
ENV_PACKUMENT_QUEUE_URL,
METRICS_NAMESPACE,
MetricName,
NPM_REPLICA_REGISTRY_URL,
+ PACKUMENT_MAX_AGE_MS,
+ PackumentGiveUpReason,
} from './constants.lambda-shared';
import { CouchChanges } from './couch-changes.lambda-shared';
import { KnownVersions } from './known-versions.lambda-shared';
import {
checkPackument,
PackumentProcessingContext,
- PackumentRequest,
- PackumentRequestReason,
} from './packument-processing.lambda-shared';
import {
parsePackumentRequest,
@@ -43,31 +42,17 @@ captureHTTPsGlobal(require('https'));
/**
* Processes packument requests: fetches each package from the registry and
- * processes the versions it serves. A request is done once the registry serves
- * the announced revision. Otherwise it is checked again later, with growing
- * waits. After about 29 hours the queue moves it to the dead-letter queue.
+ * processes the versions it serves.
*
- * This function also reads the dead-letter queue. A request that arrives from
- * there was given up on: it is logged, counted, and deleted.
+ * A request is done once the registry serves the revision the changes feed
+ * announced. Until then it is checked again with growing waits. Once a request
+ * is older than a day, its last check decides: if the registry has still not
+ * caught up, the request is given up on and deleted.
*/
export async function handler(
event: SQSEvent,
_context: Context
): Promise {
- const deadLetterQueueArn = requireEnv(ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN);
- const givenUp = event.Records.filter(
- (record) => record.eventSourceARN === deadLetterQueueArn
- );
- const pending = event.Records.filter(
- (record) => record.eventSourceARN !== deadLetterQueueArn
- );
- if (givenUp.length > 0) {
- await reportGiveUps(givenUp);
- }
- if (pending.length === 0) {
- return { batchItemFailures: [] };
- }
-
const queueUrl = requireEnv(ENV_PACKUMENT_QUEUE_URL);
let processing: PackumentProcessingContext;
try {
@@ -84,7 +69,7 @@ export async function handler(
// attempts at the queue's visibility timeout.
console.error(`Could not set up processing, retrying the batch: ${error}`);
await Promise.all(
- pending.map((record) => scheduleNextAttempt(record, queueUrl))
+ event.Records.map((record) => scheduleNextAttempt(record, queueUrl))
);
throw error;
}
@@ -93,37 +78,42 @@ export async function handler(
let outcomes = new Array();
await metricScope((metrics) => async () => {
metrics.setDimensions({});
+ const start = Date.now();
outcomes = await Promise.all(
- pending.map((record) => processRecord(record, npm, metrics, processing))
+ event.Records.map((record) =>
+ processRecord(record, npm, metrics, processing)
+ )
);
- const recovered = (reason: PackumentRequestReason) =>
- outcomes.filter((o) => o.done && o.reason === reason).length;
metrics.putMetric(
- MetricName.LAGGY_PACKUMENTS_RECOVERED,
- recovered('laggy'),
+ MetricName.METADATA_FETCH_FAILURES,
+ outcomes.filter((o) => o.result === 'unreachable').length,
Unit.Count
);
metrics.putMetric(
- MetricName.MISSING_PACKUMENTS_RECOVERED,
- recovered('missing'),
+ MetricName.FAILED_PACKUMENT_RETRIEVALS,
+ outcomes.filter((o) => FAILED_RESULTS.has(o.result)).length,
Unit.Count
);
- for (const { lag } of outcomes) {
- if (lag != null) {
+ for (const { delay, modified } of outcomes) {
+ if (delay != null) {
+ metrics.putMetric(MetricName.PACKUMENT_DELAY, delay, Unit.Seconds);
+ }
+ if (modified != null) {
metrics.putMetric(
- MetricName.LAGGY_PACKUMENT_LAG,
- lag,
+ MetricName.NPMJS_CHANGE_AGE,
+ start - modified.getTime(),
Unit.Milliseconds
);
}
}
})();
+ await reportGiveUps(outcomes);
try {
await processing.knownVersions.flush();
} catch (error) {
- // The versions were staged but not recorded. Check these packages again
- // so they get recorded.
+ // The versions were staged but not recorded. Check these packages again,
+ // even ones given up on, so they get recorded.
console.error(`Could not record the known versions: ${error}`);
for (const outcome of outcomes) {
outcome.done = false;
@@ -132,7 +122,7 @@ export async function handler(
const failures = new Array();
await Promise.all(
- pending.map(async (record, i) => {
+ event.Records.map(async (record, i) => {
if (!outcomes[i].done) {
failures.push(record.messageId);
await scheduleNextAttempt(record, queueUrl);
@@ -145,9 +135,20 @@ export async function handler(
}
interface RecordOutcome {
- readonly reason?: PackumentRequestReason;
- /** For a laggy packument that caught up: how long it took. */
- readonly lag?: number;
+ /**
+ * What the check found: `unreachable` if the fetch failed, `invalid` if the
+ * message is not a packument request.
+ */
+ readonly result: 'caught-up' | FailedResult | 'invalid';
+ /** Why the request was given up on, if it was. */
+ readonly givenUp?: PackumentGiveUpReason;
+ /**
+ * For a request that caught up after earlier checks failed: how long it
+ * took, in seconds.
+ */
+ readonly delay?: number;
+ /** When the processed packument was last modified. */
+ readonly modified?: Date;
/** Whether the message can be deleted from the queue. */
done: boolean;
}
@@ -161,89 +162,93 @@ async function processRecord(
metrics: MetricsLogger,
processing: PackumentProcessingContext
): Promise {
- let name = record.messageId;
- let reason: PackumentRequestReason | undefined;
+ let request;
try {
- const request = parsePackumentRequest(record.body);
- name = request.name;
- reason = request.reason ?? 'laggy';
- const result = await checkPackument(npm, request, metrics, processing);
- if (result !== 'caught-up') {
- return { reason, done: false };
- }
- console.log(
- `Packument for ${name} caught up with rev ${request.expectedRev} (${reason})`
- );
- return { reason, lag: lagOf(request), done: true };
+ request = parsePackumentRequest(record.body);
} catch (error) {
- console.error(
- `Failed to process the packument request for ${name}: ${error}`
- );
- return { reason, done: false };
+ // Retried until the queue moves it to the dead-letter queue.
+ console.error(`Invalid packument request ${record.messageId}: ${error}`);
+ return { result: 'invalid', done: false };
}
-}
-/**
- * Logs and counts requests that were given up on. They are deleted from the
- * dead-letter queue afterwards: nothing would redrive them.
- */
-async function reportGiveUps(records: readonly SQSRecord[]): Promise {
- await metricScope((metrics) => async () => {
- metrics.setDimensions({});
- const counts: Record = {
- laggy: 0,
- missing: 0,
- };
- for (const record of records) {
- let request: PackumentRequest;
- try {
- request = parsePackumentRequest(record.body);
- } catch {
- console.warn(
- `Giving up on an invalid packument request: ${record.body}`
- );
- continue;
- }
- const reason = request.reason ?? 'laggy';
- counts[reason] += 1;
- const problem =
- reason === 'missing'
- ? 'never served a packument for it'
- : `never served rev ${request.expectedRev}`;
- console.warn(
- `Giving up on ${reason} packument for ${
- request.name
- }: the registry ${problem} (first seen ${new Date(
- request.firstSeen
- ).toISOString()}). A version announced by the changes feed may be missing until the package publishes again.`
+ let result: 'caught-up' | FailedResult;
+ let servedRev: number | undefined;
+ let modified: Date | undefined;
+ try {
+ ({ result, servedRev, modified } = await checkPackument(
+ npm,
+ request,
+ metrics,
+ processing
+ ));
+ } catch (error) {
+ console.error(`Could not fetch the packument for ${request.name}: ${error}`);
+ result = 'unreachable';
+ }
+
+ const age = Date.now() - request.firstSeen;
+ if (result === 'caught-up') {
+ const retried = Number(record.attributes.ApproximateReceiveCount) > 1;
+ if (retried) {
+ console.log(
+ `Packument for ${request.name} caught up with rev ${request.expectedRev}`
);
- const lag = lagOf(request);
- if (lag != null) {
- metrics.putMetric(
- MetricName.LAGGY_PACKUMENT_LAG,
- lag,
- Unit.Milliseconds
- );
- }
}
- metrics.putMetric(
- MetricName.LAGGY_PACKUMENT_GIVE_UPS,
- counts.laggy,
- Unit.Count
- );
- metrics.putMetric(
- MetricName.MISSING_PACKUMENT_GIVE_UPS,
- counts.missing,
- Unit.Count
- );
- })();
+ return {
+ result,
+ delay: retried ? Math.round(age / 1_000) : undefined,
+ modified,
+ done: true,
+ };
+ }
+
+ const problem =
+ result === 'unreachable'
+ ? 'could not be reached for it'
+ : result === 'missing'
+ ? 'has no packument for it'
+ : `serves rev ${servedRev}, not rev ${request.expectedRev}`;
+ if (age < PACKUMENT_MAX_AGE_MS) {
+ console.log(`${request.name}: the registry ${problem}, checking again later`);
+ return { result, modified, done: false };
+ }
+ console.warn(
+ `Giving up on ${request.name}: the registry still ${problem} (first seen ${new Date(
+ request.firstSeen
+ ).toISOString()}). A version announced by the changes feed may be missing until the package publishes again.`
+ );
+ return { result, givenUp: GIVE_UP_REASONS[result], modified, done: true };
}
-/** How long a request has been waiting. */
-function lagOf(request: PackumentRequest): number | undefined {
- return (request.reason ?? 'laggy') === 'laggy'
- ? Date.now() - request.firstSeen
- : undefined;
+type FailedResult = 'laggy' | 'missing' | 'unreachable';
+
+const FAILED_RESULTS: ReadonlySet = new Set([
+ 'laggy',
+ 'missing',
+ 'unreachable',
+]);
+
+const GIVE_UP_REASONS: Record = {
+ laggy: PackumentGiveUpReason.LAGGY,
+ missing: PackumentGiveUpReason.MISSING,
+ unreachable: PackumentGiveUpReason.UNREACHABLE,
+};
+
+/**
+ * Counts the requests given up on, by reason and in total.
+ */
+async function reportGiveUps(outcomes: readonly RecordOutcome[]): Promise {
+ for (const reason of Object.values(GIVE_UP_REASONS)) {
+ const count = outcomes.filter((o) => o.givenUp === reason).length;
+ if (count === 0) {
+ continue;
+ }
+ await metricScope((metrics) => async () => {
+ // Also without the dimension, for the total.
+ metrics.setDimensions([{ Reason: reason }, {}]);
+ metrics.putMetric(MetricName.PACKUMENT_GIVE_UPS, count, Unit.Count);
+ })();
+ }
}
/**
@@ -257,7 +262,8 @@ async function scheduleNextAttempt(
try {
firstSeen = parsePackumentRequest(record.body).firstSeen;
} catch {
- // An invalid request gets the shortest wait, and ends up given up on.
+ // An invalid request gets the shortest wait, and ends up in the
+ // dead-letter queue.
}
try {
await setVisibilityTimeout(
diff --git a/src/package-sources/npmjs/packument-queue-processor.ts b/src/package-sources/npmjs/packument-queue-processor.ts
index 52b21d604..c06ae54bb 100644
--- a/src/package-sources/npmjs/packument-queue-processor.ts
+++ b/src/package-sources/npmjs/packument-queue-processor.ts
@@ -6,7 +6,6 @@ import { IQueue, Queue, QueueEncryption } from 'aws-cdk-lib/aws-sqs';
import { Construct } from 'constructs';
import {
ENV_KNOWN_VERSIONS_TABLE_NAME,
- ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN,
ENV_PACKUMENT_QUEUE_URL,
PACKUMENT_MAX_ATTEMPTS,
} from './constants.lambda-shared';
@@ -18,8 +17,8 @@ import { ILicenseList } from '../../backend/license-list/api';
const FUNCTION_TIMEOUT = Duration.minutes(5);
/**
- * The visibility timeout of both queues, which the function reads. Lambda
- * requires at least the function timeout; AWS recommends 6x.
+ * The visibility timeout of the queue the function reads. Lambda requires at
+ * least the function timeout; AWS recommends 6x.
*/
const QUEUE_VISIBILITY_TIMEOUT = Duration.minutes(
6 * FUNCTION_TIMEOUT.toMinutes()
@@ -38,16 +37,16 @@ export interface PackumentQueueProcessorProps {
/**
* A queue of requests to process a package from the npm registry, and the
- * function that works through it. A request is retried with back-off until the
- * registry serves the revision the changes feed announced. After about 29
- * hours it moves to the dead-letter queue, where the same function logs it as
- * given up on.
+ * function that works through it. The follower sends a request for every
+ * change entry. A request is retried with back-off until the registry serves
+ * the revision the changes feed announced, or given up on after a day. Only
+ * requests that keep failing the function move to the dead-letter queue.
*/
export class PackumentQueueProcessor extends Construct {
/** The packument requests. */
public readonly queue: IQueue;
- /** The packument requests that were given up on. */
+ /** The packument requests that kept failing the function. */
public readonly deadLetterQueue: IQueue;
/** The function processing the requests. */
@@ -60,12 +59,9 @@ export class PackumentQueueProcessor extends Construct {
) {
super(scope, id);
- // Given-up requests. The function logs and deletes them right away; they
- // are only kept while it is broken.
this.deadLetterQueue = new Queue(this, 'DLQ', {
encryption: QueueEncryption.KMS_MANAGED,
retentionPeriod: Duration.days(14),
- visibilityTimeout: QUEUE_VISIBILITY_TIMEOUT,
});
this.queue = new Queue(this, 'Queue', {
encryption: QueueEncryption.KMS_MANAGED,
@@ -86,7 +82,6 @@ export class PackumentQueueProcessor extends Construct {
FUNCTION_NAME: props.stager.functionName,
[ENV_KNOWN_VERSIONS_TABLE_NAME]: props.knownVersions.tableName,
[ENV_PACKUMENT_QUEUE_URL]: this.queue.queueUrl,
- [ENV_PACKUMENT_DEAD_LETTER_QUEUE_ARN]: this.deadLetterQueue.queueArn,
},
memorySize: 2_048,
timeout: FUNCTION_TIMEOUT,
@@ -96,14 +91,8 @@ export class PackumentQueueProcessor extends Construct {
new SqsEventSource(this.queue, {
batchSize: 10,
reportBatchItemFailures: true,
- // Be gentle with the npm registry.
- maxConcurrency: 2,
- })
- );
- this.function.addEventSource(
- new SqsEventSource(this.deadLetterQueue, {
- batchSize: 10,
- reportBatchItemFailures: true,
+ // Up to 100 packuments fetched at once, like the follower did before.
+ maxConcurrency: 10,
})
);
props.knownVersions.grantReadWriteData(this.function);
diff --git a/src/package-sources/npmjs/packument-queue.lambda-shared.ts b/src/package-sources/npmjs/packument-queue.lambda-shared.ts
index bd2af94c4..4a8122131 100644
--- a/src/package-sources/npmjs/packument-queue.lambda-shared.ts
+++ b/src/package-sources/npmjs/packument-queue.lambda-shared.ts
@@ -1,11 +1,10 @@
import {
ChangeMessageVisibilityCommand,
- GetQueueAttributesCommand,
SendMessageBatchCommand,
SendMessageBatchRequestEntry,
} from '@aws-sdk/client-sqs';
+import { Sema } from 'async-sema';
import {
- PACKUMENT_INITIAL_DELAY_SECONDS,
PACKUMENT_MAX_RETRY_DELAY_SECONDS,
PACKUMENT_MIN_RETRY_DELAY_SECONDS,
PACKUMENT_RETRY_JITTER,
@@ -19,31 +18,52 @@ const SEND_BATCH_SIZE = 10;
/** How often the failed entries of a batch send are retried. */
const MAX_SEND_ATTEMPTS = 3;
+/** The maximum number of concurrent `SendMessageBatch` requests. */
+const MAX_CONCURRENT_SENDS = 25;
+
+/** SQS delays a new message by at most 15 minutes. */
+const MAX_SQS_DELAY_SECONDS = 15 * 60;
+
+const SEND_SEMAPHORE = new Sema(MAX_CONCURRENT_SENDS);
+
/**
- * Sends packument requests to the packument queue. The first attempt happens
- * after `PACKUMENT_INITIAL_DELAY_SECONDS`.
+ * Sends packument requests to the packument queue.
*
+ * @param delaySeconds how long the requests wait before their first attempt
+ * (at most 15 minutes).
* @throws if any request could not be sent.
*/
export async function enqueuePackumentRequests(
queueUrl: string,
- requests: readonly PackumentRequest[]
+ requests: readonly PackumentRequest[],
+ delaySeconds: number = 0
): Promise {
const batches = new Array();
for (let i = 0; i < requests.length; i += SEND_BATCH_SIZE) {
batches.push(requests.slice(i, i + SEND_BATCH_SIZE));
}
- await Promise.all(batches.map((batch) => sendBatch(queueUrl, batch)));
+ const delay = Math.min(Math.round(delaySeconds), MAX_SQS_DELAY_SECONDS);
+ await Promise.all(
+ batches.map(async (batch) => {
+ await SEND_SEMAPHORE.acquire();
+ try {
+ await sendBatch(queueUrl, batch, delay);
+ } finally {
+ SEND_SEMAPHORE.release();
+ }
+ })
+ );
}
async function sendBatch(
queueUrl: string,
- batch: readonly PackumentRequest[]
+ batch: readonly PackumentRequest[],
+ delaySeconds: number
): Promise {
let entries: SendMessageBatchRequestEntry[] = batch.map((request, i) => ({
Id: i.toString(),
MessageBody: JSON.stringify(request),
- DelaySeconds: PACKUMENT_INITIAL_DELAY_SECONDS,
+ DelaySeconds: delaySeconds,
}));
for (let attempt = 1; ; attempt++) {
const response = await SQS_CLIENT.send(
@@ -66,7 +86,8 @@ async function sendBatch(
}
/**
- * Parses the body of a packument queue message.
+ * Parses the body of a packument queue message. Messages sent by earlier
+ * versions may have a `reason`, which is ignored.
*
* @throws if the body is not a packument request.
*/
@@ -75,10 +96,7 @@ export function parsePackumentRequest(body: string): PackumentRequest {
if (
typeof request.name !== 'string' ||
typeof request.expectedRev !== 'number' ||
- typeof request.firstSeen !== 'number' ||
- (request.reason != null &&
- request.reason !== 'laggy' &&
- request.reason !== 'missing')
+ typeof request.firstSeen !== 'number'
) {
throw new Error(`Not a packument request: ${body}`);
}
@@ -123,27 +141,3 @@ export async function setVisibilityTimeout(
})
);
}
-
-/**
- * The approximate number of requests in the packument queue: waiting, being
- * processed, and waiting for their next attempt.
- */
-export async function queuedPackumentRequests(
- queueUrl: string
-): Promise {
- const { Attributes: attributes = {} } = await SQS_CLIENT.send(
- new GetQueueAttributesCommand({
- QueueUrl: queueUrl,
- AttributeNames: [
- 'ApproximateNumberOfMessages',
- 'ApproximateNumberOfMessagesNotVisible',
- 'ApproximateNumberOfMessagesDelayed',
- ],
- })
- );
- return (
- Number(attributes.ApproximateNumberOfMessages ?? 0) +
- Number(attributes.ApproximateNumberOfMessagesNotVisible ?? 0) +
- Number(attributes.ApproximateNumberOfMessagesDelayed ?? 0)
- );
-}