Home

Awesome

Lighthouse4u

travis-ci

LH4U provides Google Lighthouse as a service, surfaced by both a friendly UI+API, and backed by various storage and queue clients to support a wide range of architectures.

UI

Usage

Start server via CLI:

npm i -g lighthouse4u
lh4u server --config local --config-dir ./app/config --config-base defaults --secure-config ./app/config/secure --secure-file some-private.key

Or locally to this repo via npm start (you'll need to create test/config/local.json5 by copying test/config/COPY.json5).

Architectures

With the release of v1, we've decoupled compute and storage into multiple tiers to permit a diverse set of architectures. Not only are custom storage and queue clients supported, but compute can even be run serverless.

Queue Architecture

This most closely resembles that of v0.7, but without the restrictions of being locked into Elasticsearch and RabbitMQ.

{  
  reader: {
    module: 'lighthouse4u-elasticsearch', options: { /* ... */ }
  },
  writer: {
    module: 'lighthouse4u-elasticsearch', options: { /* ... */ }
  },
  queue: { // rabbit
    module: 'lighthouse4u-amqp', options: { /* ... */ }
  }
}

Note: The lighthouse4u-elasticsearch storage client is not yet available. Happy to take contributions!

Serverless Architecture

Same as above, you're not tied to Elasticsearch. Use whatever storage and queue client fits your needs. Due to the nature of AWS Lambda, your Lighthouse "runner" (triggered via SQS) is separate from the Lighthouse4u UI+API.

Serverless example via AWS Lambda

Configuration Options

OptionTypeDefaultDesc
storereaderwriter
->.modulestringrequiredPath of client module to import. See storage clients
->.optionsobjectCollection of options supplied to storage client
queueQueue configuration
->.modulestringrequiredPath of client module to import. See queue clients
->.idleDelayMsnumber1000Time (in MS) between queue checks when queue is empty
->.enabledbooleantrueConsuming queue may be disabled
->.optionsobjectCollection of options supplied to queue client
httpHTTP(S) Server options
->.bindingsHash<HttpBinding>An object of named bindings
->.bindings.{name}HttpBindingWith {name} being the name of the binding -- can be anything, ex: myMagicBinding. See value to false if you want to disable this binding.
->.bindings.{name}.portnumber8994Port to bind to
->.bindings.{name}.sslTLS OptionsundefinedRequired to bind HTTPS/2
->.authZero or more authorization options
->.auth.{authName}HttpAuthA set of auth options keyed by any custom {authName}
->.auth.{authName}.type`basiccustom`required
->.auth.{authName}.groups`stringarray<string>`*
->.auth.{authName}.customPathstringPath of the custom module
->.auth.{authName}.optionsOptions provided to the auth module
->.authRedirectundefinedURL to redirect UI to if auth is enabled and fails
->.routesOptional set of custom routes
->.routes.{name}`stringHttpRoute`
->.routes.{name}.pathstringPath to resolve to connect middleware, relative to current working directory
->.routes.{name}.methodstringGETMethod to bind to
->.routes.{name}.routestringUses {name} if undefinedRoute to map, ala /api/test
->.staticFilesOptional to bind routes to static assets
->.staticFiles.{route}Express StaticOptions to supply to static middleware
lighthouseOptions related to Lighthouse usage
->.configLighthouseOptionsGoogle Lighthouse configuration options
->.config.extendsstringlighthouse:defaultWhat options to default to
->.config.logLevelstringwarnLevel of logging
->.config.chromeFlagsarray<string>[ '--headless', '--disable-gpu', '--no-sandbox' ]Array of CLI arguments
->.config.settingsLighthouseSettingsSee DefaultsSettings applied to Lighthouse
->.validatehash<string>Zero or more validators
->.validate.{groupName}stringPath of validation module used to determine if the response is coming from the intended server. Useful in cases where you only want to measure results coming from an intended infrastructure
->.concurrencynumber1Number of concurrently processed tasks permitted
->.reportbooltrueSave the full report, viewable in LH viewer
->.samplesAfter N lighthouse samples are taken, only the best result is recorded
->.samples.defaultnumber3Default number of lighthouse tests performed
->.samples.rangetuple<min,max>[1, 5]Minimum and maximum samples taken before returning result
->.attemptsNumber of attempts at running Google Lighthouse before giving up due to failures
->.attempts.defaultnumber2Default number of attempts before giving up
->.attempts.rangetuple<min,max>[1, 10]Minimum and maximum attempts before giving up
->.attempts.delayMsPerExponentnumber1000Exponential backoff after failure
->.delayTime (in ms) before a test is executed
->.delay.defaultnumber0Default time to wait before test can be run
->.delay.rangetuple<min,max>[0, 1000 * 60 * 60]Minimum and maximum time before test can be run
->.delay.delayMsPerExponentnumber1000 * 30Maximum time before delayed messages will be requeued

API

API - GET /api/website

Fetch zero or more website results matching the criteria.

Query String Options

OptionTypeDefaultDesc
formatstringjsonFormat of results, be it json, svg, reportHtml, or reportJson
scalenumber1Scale of svg
qstringoptionalQuery by URL or document ID
topnumber1Maximum records to return. Only applicable for json format

API - GET /api/website/compare

Similar to the single website GET, but instead compares results from q1 with q2.

Query String Options

OptionTypeDefaultDesc
formatstringjsonFormat of results, be it json or svg
scalenumber1Scale of svg
q1stringrequiredFirst query by URL or document ID
q2stringrequiredSecond query by URL or document ID

API - POST /api/website

Submit to process website with Google Lighthouse.

JSON Body Options

OptionTypeDefaultDesc
urlstringrequiredURL to process via Google Lighthouse
waitnumberoptionalBlock returning until job is complete, or the wait time (in ms) has elapsed, resulting in a partial 206 response
headershash<string>optionalCollection of HTTP headers to supply in request
secureHeadershash<string>optionalSame use as headers, but stored securely in queue, and never persisted to ElasticSearch
samplesnumber(See options.lighthouse.samples)Number of samples to take before recording result
attemptsnumber(See options.lighthouse.attempts)Number of failure attempts before giving up
hostOverridestringoptionalMap host of request to an explicit IP. Not yet supported by Chrome in Headless mode
delaynumber(See options.lighthouse.delay)Delay (in milliseconds) before test will be performed. Useful if the intended service or domain is not expected to be available for some time
groupstringunknownGroup to categorize result to. Useful when searching/filtering on different groups of results
reportbooltrueIf the full report should be stored, allowing for viewing in LH Viewer
auditMode`false'simple''details'
cookies`array<{name=stringCookie}>`optional
cookies[idx].valuestringrequiredValue to set for cookie
cookies[idx].domainstringoptionalDomain to apply cookie to. Defaults to root of requestedUrl domain
cookies[idx].urlstringoptionalIf the page required to apply cookie to differs from the requestedUrl you can set that here
cookies[idx].pathstringoptionalPath to apply to cookie
cookies[idx].securebooleanoptionalIs cookie secured
cookies[idx].httpOnlybooleanoptionalHTTP only
commandsarray<Commmand>optionalDevTool Commands to be executed prior to running Lighthouse
commands[idx].commandstringrequiredDevTool Command to execute
commands[idx].optionsobjectrequiredDevTool Command Options to supply command
metaobjectoptionalObject containing metadata that will be attached to final lighthouse results

Command

Storage Clients

Queue Clients

Secure Configuration

Optionally you may run LH4U with the --secure-config {secureConfigPath} and --secure-file {securePrivateFile} powered by Config Shield.

npm i -g config-shield
cshield ./app/config/secure some-private.key
> help
> set queue { options: { url: 'amqp://lh4u_user:someSuperSecretPassword@rmq.on-my-domain.com:5672/lh4u' } }
> get queue
: { "options": { "url": "amqp://lh4u_user:someSuperSecretPassword@rmq.on-my-domain.com:5672/lh4u" } }
> save
> exit

The example above will allow you to merge sensitive credentials with your existing public configuration. Only options defined in the secure config will be deeply merged.