relay

package module
v0.0.0-...-8dc4135 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 24, 2020 License: Apache-2.0 Imports: 43 Imported by: 0

README

LaunchDarkly Relay Proxy

What is it?

The LaunchDarkly Relay Proxy establishes a connection to the LaunchDarkly streaming API, then proxies that stream connection to multiple clients.

The Relay Proxy lets a number of servers connect to a local stream instead of making a large number of outbound connections to stream.launchdarkly.com.

The Relay Proxy can be configured to proxy multiple environment streams, even across multiple projects. It can also be used as a local proxy that forwards events to events.launchdarkly.com. This can be useful if you are load balancing Relay Proxy instances behind a proxy that times out HTTP connections (e.g. Elastic Load Balancers).

When should it be used?

Refer to our documentation for guidance on situations where the Relay Proxy should be used.

Getting started

Refer to our documentation for instructions on getting started with using the Relay Proxy.

Command-line arguments

Argument Default Description
--config /etc/ld-relay.conf configuration file location
--allow-missing-file if specified, a --config option for a nonexistent file will be ignored
--from-env if specified, configuration will be read from environment variables

See the next section for how these options may be used separately or together.

Specifying a configuration

Configuration options may be passed in a file, or in environment variables, or both. The command-line arguments for these work as follows:

  • If you pass no arguments at all, it will attempt to load /etc/ld-relay.conf.
  • If you pass --config FILEPATH, it will load that file. The file must exist.
  • If you pass --config FILEPATH --allow-missing-file, it will try to load the file only if the file exists.
  • If you pass --from-env, it will read configuration options from environment variables.
  • If you pass both --config and --from-env, it will both load the specified file and use the environment variables. The environment variables will override any equivalent options from the file.

An example of why you might use both configuration modes together is if you want to deploy a base.conf file that contains all of the global configuration for your relay instance, but for security reasons you do not want your SDK key to appear in that file. Assuming that the name you gave your LaunchDarkly environment in the file is "production", your command line might look like this:

LD_ENV_production={your_SDK_key} ./ld-relay --config base.conf --from-env

Or, you might wish to create a package containing the ld-relay binary and a file with some basic options, which you will be reusing in different contexts with completely different sets of environments. You could completely omit the environment configuration from the file, and pass it all in variables:

LD_ENV_firstenv={SDK key for firstenv} LD_PREFIX_firstenv={Redis prefix for firstenv} \
  LD_ENV_secondenv={SDK key for secondenv} LD_PREFIX_secondenv={Redis prefix for secondenv} \
  ./ld-relay --config base.conf --from-env

Configuration file format and environment variables

The configuration file format is an INI-like one, based on Git configuration format (as implemented by a fork of the gcfg package).

Every configuration file option has an equivalent environment variable. You may use either method: see "Specifying a configuration". Note that for boolean settings, a value of either true or 1 is considered true while any other value (or an empty value) is considered false.

File section: [Main]
Property in file Environment var Type Default Description
streamUri STREAM_URI URI (1) URI for the LaunchDarkly streaming service.
baseUri BASE_URI URI (1) URI for the LaunchDarkly polling service.
exitOnError EXIT_ON_ERROR Boolean false Close the Relay Proxy if it encounters any error during initialization.
exitAlways EXIT_ALWAYS Boolean false Close the Relay Proxy immediately after initializing all environments (do not start an HTTP server). (2)
ignoreConnectionErrors IGNORE_CONNECTION_ERRORS Boolean false Ignore any initial connectivity issues with LaunchDarkly. Best used when network connectivity is not reliable.
port PORT Number 8030 Port the Relay Proxy should listen on.
heartbeatIntervalSecs HEARTBEAT_INTERVAL Number 180 Interval (in seconds) for heartbeat messages to prevent read timeouts on streaming connections.
tlsEnabled TLS_ENABLED Boolean false Enable TLS on the Relay Proxy.
tlsCert TLS_CERT String Required if tlsEnabled is true. Path to TLS certificate file.
tlsKey TLS_KEY String Required if tlsEnabled is true. Path to TLS private key file.
tlsMinVersion TLS_MIN_VERSION String Set to "1.2", etc., to enforce a minimum TLS version for secure requests.
logLevel LOG_LEVEL String info Should be debug, info, warn, error, or none; see Logging

(1) The default values for streamUri and baseUri are https://app.launchdarkly.com and https://stream.launchdarkly.com. You should never need to change these URIs unless a) you are using a special instance of the LaunchDarkly service, in which case support will tell you how to set them, or b) you are accessing LaunchDarkly via a reverse proxy or some other mechanism that rewrites URLs.

(2) The exitAlways mode is intended for use cases where you do not want to maintain a long-running Relay Proxy instance, but only execute it at specific times to get flags; this is only useful if you have enabled Redis or another database, so that it will store the flags there.

File section: [Events]
Property in file Environment var Type Default Description
sendEvents USE_EVENTS Boolean false When enabled, LD-Relay will send analytic events it receives to LaunchDarkly.
eventsUri EVENTS_HOST URI (2) URI for the LaunchDarkly events service
flushIntervalSecs EVENTS_FLUSH_INTERVAL Number 5 Controls how long the SDK buffers events before sending them back to our server. If your server generates many events per second, we suggest decreasing the flush interval and/or increasing capacity to meet your needs.
samplingInterval EVENTS_SAMPLING_INTERVAL Number 0 Sends one out of this many events as a random sampling.
capacity EVENTS_CAPACITY Number 1000 Maximum number of events to accumulate for each flush interval.
inlineUsers EVENTS_INLINE_USERS Boolean false When enabled, individual events (if full event tracking is enabled for the feature flag) will contain all non-private user attributes.

(2) See note (1) above. The default value for eventsUri is https://events.launchdarkly.com.

File section: [Redis]
Property in file Environment var Type Default Description
n/a USE_REDIS Boolean false If you are using environment variables, set this to enable Redis.
host REDIS_HOST String localhost Hostname of the Redis database. Redis is enabled if this or url is set.
port REDIS_PORT Number 6379 Port of the Redis database. Note that if you are using environment variables, setting REDIS_PORT to a string like tcp://host:port sets both the host and the port; this is used in Docker.
url REDIS_URL String URL of the Redis database (overrides host & port).
tls REDIS_TLS Boolean false If true, will use a secure connection to Redis (not all Redis servers support this). If you specified a redis:// URL, setting tls to true will change it to rediss://.
password REDIS_PASSWORD String Optional password if Redis require authentication.
localTtl CACHE_TTL Number 30000 Length of time (in milliseconds) that database items can be cached in memory.

Note that the TLS and password options can also be specified as part of the URL: rediss:// instead of redis:// enables TLS, and redis://:password@host instead of redis://host sets a password. You may want to use the separate options instead if, for instance, you want your configuration file to contain the basic Redis configuration, but for security reasons you would rather set the password in an environment variable (REDIS_PASSWORD).

File section: [DynamoDB]
Property in file Environment var Type Default Description
enabled USE_DYNAMODB Boolean false Enables DynamoDB.
tableName DYNAMODB_TABLE String The DynamoDB table name, if you are using the same table for all environments. Otherwise, omit this and specify it in each environment section. (Note, credentials and region are controlled by the usual AWS environment variables and/or local AWS configuration files.)
url DYNAMODB_URL String The service endpoint if you are using a local DynamoDB instance instead of the regular service.
localTtl CACHE_TTL Number 30000 Length of time (in milliseconds) that database items can be cached in memory.

The AWS credentials and region for DynamoDB are not part of the Relay configuration; they should be set using either the standard AWS environment variables or a local AWS configuration file, as documented for the AWS CLI.

File section: [Consul]
Property in file Environment var Type Default Description
n/a USE_CONSUL Boolean false If you are using environment variables, set this to enable Consul.
host CONSUL_HOST String localhost Hostname of the Consul server. Consul is enabled if this is set.
localTtl CACHE_TTL Number 30000 Length of time (in milliseconds) that database items can be cached in memory.
File section: [Environment "NAME"]

The Relay Proxy allows you to proxy any number of LaunchDarkly environments; there must be at least one. In a configuration file, each of these is a separate section in the format [Environment "MyEnvName"], where MyEnvName is a unique identifier for the environment (this does not have to match the environment name on your LaunchDarkly dashboard, but it is recommended to). If you are using environment variables, you will add the MyEnvName identifier to the variable name prefix for each property. See examples below.

Property in file Environment var Type Description
sdkKey LD_ENV_MyEnvName String Server-side SDK key for the environment. Required.
mobileKey LD_MOBILE_KEY_MyEnvName String Mobile key for the environment. Required if you are proxying mobile SDK functionality.
envId LD_CLIENT_SIDE_ID_MyEnvName String Client-side ID for the environment. Required if you are proxying client-side JavaScript-based SDK functionality.
prefix LD_PREFIX_MyEnvName String If using a Redis, Consul, or DynamoDB feature store, this string will be added to all database keys to distinguish them from any other environments that are using the database.
tableName LD_TABLE_NAME_MyEnvName String If using DynamoDB, you can specify a different table for each environment. (Or, specify a single table in the [DynamoDB] section and use prefix to distinguish the environments.)
allowedOrigin LD_ALLOWED_ORIGIN_MyEnvName URI If provided, adds CORS headers to prevent access from other domains. This variable can be provided multiple times per environment (if using the LD_ALLOWED_ORIGIN_MyEnvName variable, specify a comma-delimited list).
logLevel LD_LOG_LEVEL_MyEnvName String Should be debug, info, warn, error, or none; see Logging
ttlMinutes LD_TTL_MINUTES_MyEnvName Number HTTP caching TTL for the PHP polling endpoints (see Using with PHP)

In the following examples, there are two environments, each of which has a server-side SDK key and a mobile key. Debug-level logging is enabled for the second one.

# Configuration file example

[Environment "Spree Project Production"]
    sdkKey = "SPREE_PROD_SDK_KEY"
    mobileKey = "SPREE_PROD_MOBILE_KEY"

[Environment "Spree Project Test"]
    sdkKey = "SPREE_TEST_SDK_KEY"
    mobileKey = "SPREE_TEST_MOVILE_KEY"
    logLevel = "debug"
# Environment variables example

LD_ENV_Spree_Project_Production=SPREE_PROD_SDK_KEY
LD_MOBILE_KEY_Spree_Project_Production=SPREE_PROD_MOBILE_KEY
LD_ENV_Spree_Project_Test=SPREE_TEST_SDK_KEY
LD_MOBILE_KEY_Spree_Project_Test=SPREE_TEST_MOBILE_KEY
File section: [Datadog]
Property in file Environment var Type Default Description
enabled USE_DATADOG Boolean false If true, enables exporting to Datadog.
statsAddr DATADOG_STATS_ADDR URI URI of the DogStatsD agent. If not provided, stats will not be collected. Example: localhost:8125
traceAddr DATADOG_TRACE_ADDR URI URI of the Datadog trace agent. If not provided, traces will not be collected. Example: localhost:8126
tag DATADOG_TAG_TagName String A tag to be applied to all metrics sent to datadog. This variable can be provided multiple times (see below).
prefix DATADOG_PREFIX String The metrics prefix to be used by Datadog.

There may be any number of DataDog tags. Use the following format:

# Configuration file example

[Datadog]
    enabled = true
    tag = firstTagName:firstTagValue
    tag = secondTagName:secondTagValue
# Environment variables example

USE_DATADOG=1
DATADOG_TAG_firstTagName=firstTagValue
DATADOG_TAG_secondTagName=secondTagValue
File section: [Stackdriver]
Property in file Environment var Type Default Description
enabled USE_STACKDRIVER Boolean false If true, enables exporting metrics and traces to Stackdriver.
projectID STACKDRIVER_PROJECT_ID String Google cloud project ID.
prefix STACKDRIVER_PREFIX String The metrics prefix to be used by Stackdriver.
File section: [Prometheus]
Property in file Environment var Type Default Description
enabled USE_PROMETHEUS Boolean false If true, enables exporting traces to Prometheus.
port PROMETHEUS_PORT Number 8031 The port that the Relay Proxy will provide the /metrics endpoint on.
prefix PROMETHEUS_PREFIX String The metrics prefix to be used by Prometheus.
File section: [Proxy]
Property in file Environment var Type Default Description
url PROXY_URL String All Relay Proxy network traffic will be sent through this HTTP proxy if specified.
user PROXY_AUTH_USER String Username for proxy authentication, if applicable.
password PROXY_AUTH_PASSWORD String Password for proxy authentication, if applicable.
domain PROXY_AUTH_DOMAIN String Domain name for proxy authentication, if applicable.
caCertFiles PROXY_CA_CERTS String Comma-delimited list of file paths to additional CA certificates that should be trusted (in PEM format).
ntlmAuth PROXY_AUTH_NTLM Boolean false Enables NTLM proxy authentication (requires user, password, and domain).

Mobile and client-side flag evaluation

The Relay Proxy may be optionally configured with a mobile SDK key, and/or an environment ID to enable flag evaluation support for mobile and client-side LaunchDarkly SDKs (Android, iOS, and JavaScript). In these examples, one environment allows only mobile and another allows only client-side JavaScript, but you could also have an environment that uses both.

# Configuration file example

[Environment "Spree Mobile Production"]
    sdkKey = "SPREE_MOBILE_PROD_SDK_KEY"
    mobileKey = "SPREE_MOBILE_PROD_MOBILE_KEY"

[Environment "Spree Webapp Production"]
    sdkKey = "SPREE_WEB_PROD_SDK_KEY"
    envId = "SPREE_WEB_PROD_ENV_ID"
    allowedOrigin = "http://example.org"
    allowedOrigin = "http://another_example.net"
# Environment variables example

LD_ENV_Spree_Mobile_Production=SPREE_MOBILE_PROD_SDK_KEY
LD_MOBILE_KEY_Spree_Mobile_Production=SPREE_MOBILE_PROD_MOBILE_KEY
LD_ENV_Spree_Webapp_Production=SPREE_WEB_PROD_SDK_KEY
LD_CLIENT_SIDE_ID_Spree_Webapp_Production=SPREE_WEB_PROD_ENV_ID

Once a mobile key or environment ID has been configured, you may set the baseUri parameter to the host and port of your Relay Proxy instance in your mobile/client-side SDKs. If you are exposing any of the client-side relay endpoints externally, HTTPS should be configured with a TLS termination proxy.

Event forwarding

The Relay Proxy can also be used to forward events to events.launchdarkly.com (unless you have specified a different URL for the events service in your configuration). When enabled, the Relay Proxy will buffer and forward events posted to /bulk to the corresponding endpoint in the events service. The primary use case for this is PHP environments, where the performance of a local proxy makes it possible to synchronously flush analytics events. To set up event forwarding, follow one of these examples:

# Configuration file example

[Events]
    sendEvents = true
    flushIntervalSecs = 5
    samplingInterval = 0
    capacity = 1000
    inlineUsers = false
# Environment variables example

USE_EVENTS=true
EVENTS_FLUSH_INTERVAL=5
EVENTS_SAMPLING_INTERVAL=0
EVENTS_CAPACITY=1000

This configuration will buffer events for all environments specified in the configuration. The events will be flushed every flushIntervalSecs. To point our SDKs to the Relay Proxy for event forwarding, set the eventsUri in the SDK to the host and port of your relay instance (or preferably, the host and port of a load balancer fronting your relay instances). Setting inlineUsers to true preserves full user details in every event (the default is to send them only once per user in an "index" event).

Persistent storage

You can configure Relay Proxy nodes to persist feature flag settings in Redis, DynamoDB, or Consul. This provides durability in case of (e.g.) a temporary network partition that prevents the Relay Proxy from communicating with LaunchDarkly's servers. See Using a persistent feature store.

# Configuration file examples

[Redis]
    host = "localhost"
    port = 6379
    localTtl = 30000

[DynamoDB]
    tableName = "my-feature-flags"
    localTtl = 30000

[Consul]
    host = "localhost"
    localTtl = 30000
# Environment variables examples

USE_REDIS=1
REDIS_HOST=localhost
REDIS_PORT=6379
CACHE_TTL=30000

USE_DYNAMODB=1
DYNAMODB_TABLE=my-feature-flags
CACHE_TTL=30000

USE_CONSUL=1
CONSUL_HOST=localhost
CACHE_TTL=30000

Note that the Relay Proxy can only use one of these at a time; for instance, enabling both Redis and DynamoDB is an error.

Also note that the LaunchDarkly SDK clients have their own options for configuring persistent storage. If you are using daemon mode (see below) then the clients need to be using the same storage configuration as the Relay Proxy. If you are not using daemon mode, then the two configurations are completely independent, e.g. you could have a relay using Redis, but a client using Consul or not using persistent storage at all.

In case the database becomes unavailable, Relay's behavior (based on its use of the Go SDK) depends on the CACHE_TTL setting:

  • If the TTL is a positive number, then the last known flag data will remain cached in memory for that amount of time, after which Relay will be unable to serve flags to SDK clients. Once the database becomes available again, Relay will request all of the flags from LaunchDarkly again and write the latest values to the database.
  • If the TTL is a negative number, then the in-memory cache never expires. Relay will continue serving flags to SDK clients, and will update the cache if it receives any flag updates from LaunchDarkly. As Relay will only read from the database upon service startup, it is recommended that you avoid restarting Relay while detecting database downtime. Once the database becomes available again, Relay will write the contents of the cache back to the database. Use the "cached forever" mode with caution: it means that in a scenario where multiple Relay processes are sharing the database, and the current process loses connectivity to LaunchDarkly while other processes are still receiving updates and writing them to the database, the current process will have stale data.

Note that the in-memory cache only helps SDKs using the Relay in proxy mode. SDKs configured to use daemon mode are connected to read directly from the database. Learn more.

Relay proxy mode

The Relay Proxy is typically deployed in relay proxy mode. In this mode, several Relay Proxy instances are deployed in a high-availability configuration behind a load balancer. Relay Proxy nodes do not need to communicate with each other, and there is no master or cluster. This makes it easy to scale the Relay Proxy horizontally by deploying more nodes behind the load balancer.

Relay Proxy with load balancer

Daemon mode

Optionally, you can configure our SDKs to communicate directly to the persistent store. If you go this route, there is no need to put a load balancer in front of the Relay Proxy; we call this daemon mode. This is the preferred way to use LaunchDarkly with PHP (as there's no way to maintain persistent stream connections in PHP).

Relay Proxy in daemon mode

In this example, the persistent store is in Redis. To set up the Relay Proxy in this mode, provide a Redis host and port, and supply a Redis key prefix for each environment in your configuration:

# Configuration file example

[Redis]
    host = "localhost"
    port = 6379
    localTtl = 30000

[Environment "Spree Project Production"]
    prefix = "ld:spree:production"
    sdkKey = "SPREE_PROD_SDK_KEY"

[Environment "Spree Project Test"]
    prefix = "ld:spree:test"
    sdkKey = "SPREE_TEST_SDK_KEY"
# Environment variables example

USE_REDIS=1
REDIS_HOST=localhost
REDIS_PORT=6379
CACHE_TTL=30000
LD_ENV_Spree_Project_Production=SPREE_PROD_SDK_KEY
LD_PREFIX_Spree_Project_Production=ld:spree:production
LD_ENV_Spree_Project_Test=SPREE_TEST_SDK_KEY
LD_PREFIX_Spree_Project_Test=ld:spree:test

(The per-environment "prefix" setting can be used the same way with Consul or DynamoDB. Alternately, with DynamoDB you can use a separate table name for each environment.)

The localTtl/CACHE_TTL parameter controls the length of time (in milliseconds) that the Relay Proxy will cache data in memory so that feature flag requests do not always hit the database; see persistent storage.

You will then need to configure your SDK to connect to Redis directly.

Flag evaluation endpoints

If you're building an SDK for a language which isn't officially supported by LaunchDarkly, or would like to evaluate feature flags internally without an SDK instance, the Relay Proxy provides endpoints for evaluating all feature flags for a given user. These endpoints support the GET and REPORT http verbs to pass in users either as base64url encoded path parameters, or in the request body, respectively.

Example curl requests (default local URI and port):

curl -X GET -H "Authorization: YOUR_SDK_KEY" localhost:8030/sdk/eval/users/eyJrZXkiOiAiYTAwY2ViIn0=

curl -X REPORT localhost:8030/sdk/eval/user -H "Authorization: YOUR_SDK_KEY" -H "Content-Type: application/json" -d '{"key": "a00ceb", "email":"barnie@example.org"}'

Performance, scaling, and operations

We have done extensive load tests on the Relay Proxy in AWS/EC2. We have also collected a substantial amount of data based on real-world customer use. Based on our experience, we have several recommendations on how to best deploy, operate, and scale the Relay Proxy:

  • Networking performance is paramount. Memory and CPU are not as critical. The Relay Proxy should be deployed on boxes with good networking performance. On EC2, we recommend using an instance with Moderate to High networking performance such as m4.xlarge. On an m4.xlarge instance, a single Relay Proxy node can easily manage 20,000 concurrent connections.

  • If using an Elastic Load Balancer in front of the Relay Proxy, you may need to pre-warm the load balancer whenever connections to the Relay Proxy are cycled. This might happen when you deploy a large number of new servers that connect to the Relay Proxy, or upgrade the Relay Proxy itself.

Health check

The Relay Proxy has an additional status endpoint which provides the current status of all of its streaming connections. This can obtained by querying the URL path /status with a GET request.

Logging

Like the Go SDK, the Relay Proxy supports four logging levels: Debug, Info, Warn, and Error, with Debug being the most verbose. Setting the minimum level to Info (the default) means Debug is disabled; setting it to Warn means Debug and Info are disabled; etc.

There are two categories of log output: global messages and per-environment messages. Global messages are from the general Relay Proxy infrastructure - for instance, when it has successfully started up, or when it has received an HTTP request. Per-environment messages are for the Relay Proxy's interaction with LaunchDarkly for a specific one of your configured environments - for instance, receiving a flag update or sending analytics events. These can be configured separately: the logLevel parameter in [main] or the LOG_LEVEL variable sets the minimum level for global messages, and the logLevel parameter in [environment] or the LD_LOG_LEVEL_envName variable sets the minimum level for per-environment messages in a specific environment. This is because you may wish to see more verbose output in one category than another, or in one environment than another. If you do not specify a log level for an individual environment, it defaults to the global log level.

Note that debug-level logging for per-environment messages may include user properties and feature flag keys.

Proxied endpoints

The table below describes the endpoints proxied by the Relay Proxy. In this table:

  • user is the base64 representation of a user JSON object (e.g. {"key": "user1"} => eyJrZXkiOiAidXNlcjEifQ==).
  • clientId is the 32-hexdigit Client-side ID (e.g. 6488674dc2ea1d6673731ba2)
  • "Auth Header" indicates whether the HTTP request should have an Authorization header that is equal to the SDK key, the mobile key, or neither.
Endpoint Method Auth Header Description
/sdk/eval/clientId/users/user GET n/a Returns flag evaluation results for a user
/sdk/eval/clientId/user REPORT n/a Same as above but request body is user JSON object
/sdk/evalx/clientId/users/user GET n/a Returns flag evaluation results and additional metadata
/sdk/evalx/clientId/user REPORT n/a Same as above but request body is user JSON object
/sdk/flags GET sdk For PHP SDK
/sdk/flags/flagKey GET sdk For PHP SDK
/sdk/segments/segmentKey GET sdk For PHP SDK
/sdk/goals/clientId GET n/a For JS and other client-side SDKs
/mobile POST mobile For receiving events from mobile SDKs
/mobile/events POST mobile Same as above
/mobile/events/bulk POST mobile Same as above
/mobile/events/diagnostic POST mobile Same as above
/bulk POST sdk For receiving events from server-side SDKs
/diagnostic POST sdk Same as above
/events/bulk/clientId POST, OPTIONS n/a For receiving events from JS and other client-side SDKs
/events/diagnostic/clientId POST, OPTIONS n/a Same as above
/a/clientId.gif?d=events GET, OPTIONS n/a Same as above
/all GET sdk SSE stream for all data
/flags GET sdk Legacy SSE stream for flag data
/ping GET sdk SSE endpoint that issues "ping" events when there are flag data updates
/ping/clientId GET n/a Same as above but with JS and client-side authorization.
/mping GET mobile SSE endpoint that issues "ping" events when flags should be re-evaluated
/meval/user GET mobile SSE stream of "ping" and other events for mobile clients
/meval REPORT mobile Same as above but request body is user JSON object
/eval/clientId/user GET n/a SSE stream of "ping" and other events for JS and other client-side SDK listeners
/eval/clientId REPORT n/a Same as above but request body is user JSON object

Exporting metrics and traces

The Relay Proxy may be configured to export statistics and route traces to Datadog, Stackdriver, and Prometheus. See the configuration section for configuration instructions.

The following metrics are supported:

  • connections: The number of current proxied streaming connections.
  • newconnections: The number of streaming connections created.
  • requests: Number of requests received.

Metrics can be filtered by the following tags:

  • platformCategoryTagKey: The platform a metric was generated by (e.g. server, browser, or client-side).
  • env: The name of the LaunchDarkly environment.
  • route: The request route.
  • method: The http method used for the request.
  • userAgent: The user agent used to make the request, typically a LaunchDarkly SDK version. Example: "Node/3.4.0"

Note: Traces for stream connections will trace until the connection is closed.

Using with PHP

The PHP SDK communicates differently with LaunchDarkly than the other SDKs because it does not support long-lived streaming connections. It must either poll for flags on demand via HTTP, or get them from Redis or another database. The latter is much more efficient and is therefore the preferred approach, but if you are not using a database, the Relay Proxy can handle HTTP requests from PHP.

However, it is highly recommended that if you do this, you use the ttlMinutes parameter in the environment configuration. This is equivalent to the TTL setting for the environment on your LaunchDarkly dashboard, but must be set here separately because the Relay Proxy does not have access to those dashboard properties. This will cause HTTP responses from the PHP endpoints to have a Cache-Control: max-age so that the PHP SDK will not make additional HTTP requests for the same flag more often than that interval. Note that this may result in different PHP application instances receiving flag updates at slightly different times as their HTTP caches will not be exactly in sync. It does not affect any SDKs other than PHP.

Docker

Using Docker is not required, but if you prefer using a Docker container we provide a Docker entrypoint to make this as easy as possible.

To build the ld-relay container:

$ docker build -t ld-relay .

In Docker, the config file is expected to be found at /ldr/ld-relay.conf unless you are using environment variables to configure the Relay Proxy (see the configuration section).

Docker examples

To run a single environment, without Redis:

$ docker run --name ld-relay -e LD_ENV_test="sdk-test-sdkKey" ld-relay

To run multiple environments, without Redis:

$ docker run --name ld-relay -e LD_ENV_test="sdk-test-sdkKey" -e LD_ENV_prod="sdk-prod-sdkKey" ld-relay

To run a single environment, with Redis:

$ docker run --name redis redis:alpine
$ docker run --name ld-relay --link redis:redis -e USE_REDIS=1 -e LD_ENV_test="sdk-test-sdkKey" ld-relay

To run multiple environment, with Redis:

$ docker run --name redis redis:alpine
$ docker run --name ld-relay --link redis:redis -e USE_REDIS=1 -e LD_ENV_test="sdk-test-sdkKey" -e LD_PREFIX_test="ld:default:test" -e LD_ENV_prod="sdk-prod-sdkKey" -e LD_PREFIX_prod="ld:default:prod" ld-relay

Windows

To register the Relay Proxy as a service, run a command prompt as Administrator:

$ sc create ld-relay DisplayName="LaunchDarkly Relay Proxy" start="auto" binPath="C:\path\to\ld-relay.exe -config C:\path\to\ld-relay.conf"

Integrating the Relay Proxy into your own application

You can also use the Relay Proxy to handle endpoints in your own application if you don't want to use the default ld-relay application. Below is an example using Gorilla of how you might instantiate a relay inside your web server beneath a path called "/relay":

router := mux.NewRouter()
configFileName := "path/to/my-config-file"
cfg := relay.DefaultConfig
if err := relay.LoadConfigFile(&cfg, configFileName); err != nil {
    log.Fatalf("Error loading config file: %s", err)
}
r, err := relay.NewRelay(cfg, relay.DefaultClientFactory)
if err != nil {
    log.Fatalf("Error creating relay: %s", err)
}
router.PathPrefix("/relay").Handler(r)

The above example uses a configuration file. You can also pass in a relay.Config struct that you have filled in directly:

cfg := relay.DefaultConfig
cfg.Main.Port = 5000
cfg.Environment = map[string]*relay.EnvConfig{
    "Spree Project Production": &relay.EnvConfig{
        SdkKey: "SPREE_PROD_API_KEY",
    }
}
r, err := relay.NewRelay(cfg, relay.DefaultClientFactory)

Or, you can parse the configuration from a string that is in the same format as the configuration file, using the same gcfg package that ld-relay uses:

import "github.com/launchdarkly/gcfg"

configString := `[main]\nport = 5000\n[environment "Spree Project Production"]\nsdkKey = "SPREE_PROD_API_KEY"`

cfg := relay.DefaultConfig
if err := gcfg.ReadStringInto(&cfg, configString); err != nil {
    log.Fatalf("Error loading config file: %s", err)
}
r, err := relay.NewRelay(cfg, relay.DefaultClientFactory)

Testing

After installing a compatible version of Go, run make test to build and run unit tests. To run integration runs, run make integration-test. To run the linter, run make lint.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultConfig = Config{
	Main: MainConfig{
		BaseUri:               defaultBaseURI,
		StreamUri:             defaultStreamURI,
		HeartbeatIntervalSecs: defaultHeartbeatIntervalSecs,
		Port:                  defaultPort,
	},
	Events: events.Config{
		Capacity:          defaultEventCapacity,
		EventsUri:         defaultEventsURI,
		FlushIntervalSecs: defaultFlushIntervalSecs,
	},
	Redis: RedisConfig{
		LocalTtl: defaultDatabaseLocalTTLMs,
	},
	Consul: ConsulConfig{
		LocalTtl: defaultDatabaseLocalTTLMs,
	},
	DynamoDB: DynamoDBConfig{
		LocalTtl: defaultDatabaseLocalTTLMs,
	},
	MetricsConfig: MetricsConfig{
		Prometheus: PrometheusConfig{
			Port: defaultPrometheusPort,
		},
	},
}

DefaultConfig contains defaults for all relay configuration sections.

If you are incorporating Relay into your own code and configuring it programmatically, it is best to start by copying relay.DefaultConfig and then changing only the fields you need to change.

Functions

func InitializeMetrics

func InitializeMetrics(c MetricsConfig) error

InitializeMetrics reads a MetricsConfig and registers OpenCensus exporters for all configured options. Will only initialize exporters on the first call to InitializeMetrics.

func LoadConfigFile

func LoadConfigFile(c *Config, path string) error

LoadConfigFile reads a configuration file into a Config struct and performs basic validation.

The Config parameter should be initialized with default values first.

func LoadConfigFromEnvironment

func LoadConfigFromEnvironment(c *Config) error

LoadConfigFromEnvironment sets parameters in a Config struct from environment variables.

The Config parameter should be initialized with default values first.

func UserV2FromBase64

func UserV2FromBase64(base64User string) (*ld.User, error)

UserV2FromBase64 decodes a base64-encoded go-server-sdk v2 user. If any decoding/unmarshaling errors occur or the user is missing the 'key' attribute an error is returned.

func ValidateConfig

func ValidateConfig(c *Config) error

ValidateConfig ensures that the configuration does not contain contradictory properties.

Types

type CommonMetricsConfig

type CommonMetricsConfig struct {
	Enabled bool
	Prefix  string
}

CommonMetricsConfig contains fields that are common to DatadogCOnfig, StackdriverConfig, and PrometheusConfig.

type Config

type Config struct {
	Main        MainConfig
	Events      events.Config
	Redis       RedisConfig
	Consul      ConsulConfig
	DynamoDB    DynamoDBConfig
	Environment map[string]*EnvConfig
	Proxy       httpconfig.ProxyConfig
	MetricsConfig
}

Config describes the configuration for a relay instance.

If you are incorporating Relay into your own code and configuring it programmatically, it is best to start by copying relay.DefaultConfig and then changing only the fields you need to change.

type ConsulConfig

type ConsulConfig struct {
	Host     string
	LocalTtl int
}

ConsulConfig configures the optional Consul integration, which is used only if Host is non-empty.

This corresponds to the [Consul] section in the configuration file.

type DatadogConfig

type DatadogConfig struct {
	TraceAddr *string
	StatsAddr *string
	Tag       []string
	CommonMetricsConfig
}

DatadogConfig configures the optional Datadog integration, which is used only if Enabled is true.

This corresponds to the [Datadog] section in the configuration file.

type DynamoDBConfig

type DynamoDBConfig struct {
	Enabled   bool
	TableName string
	Url       string
	LocalTtl  int
}

DynamoDBConfig configures the optional DynamoDB integration, which is used only if Enabled is true.

This corresponds to the [DynamoDB] section in the configuration file.

type EnvConfig

type EnvConfig struct {
	SdkKey             string
	ApiKey             string // deprecated, equivalent to SdkKey
	MobileKey          *string
	EnvId              *string
	Prefix             string // used only if Redis, Consul, or DynamoDB is enabled
	TableName          string // used only if DynamoDB is enabled
	AllowedOrigin      *[]string
	InsecureSkipVerify bool
	LogLevel           string
	TtlMinutes         int
}

EnvConfig describes an environment to be relayed. There may be any number of these.

This corresponds to one of the [environment "env-name"] sections in the configuration file. In the Config.Environment map, each key is an environment name and each value is an EnvConfig.

func (EnvConfig) GetLogLevel

func (c EnvConfig) GetLogLevel() ldlog.LogLevel

type ExporterConfig

type ExporterConfig interface {
	// contains filtered or unexported methods
}

ExporterConfig is used internally to hold options for metrics integrations.

type LdClientContext

type LdClientContext interface {
	Initialized() bool
}

LdClientContext defines a minimal interface for a LaunchDarkly client

func DefaultClientFactory

func DefaultClientFactory(sdkKey string, config ld.Config) (LdClientContext, error)

DefaultClientFactory creates a default client for connecting to the LaunchDarkly stream

type MainConfig

type MainConfig struct {
	ExitOnError            bool
	ExitAlways             bool
	IgnoreConnectionErrors bool
	StreamUri              string
	BaseUri                string
	Port                   int
	HeartbeatIntervalSecs  int
	TLSEnabled             bool
	TLSCert                string
	TLSKey                 string
	TLSMinVersion          string
	LogLevel               string
}

MainConfig contains global configuration options for Relay.

This corresponds to the [Main] section in the configuration file.

func (MainConfig) GetLogLevel

func (c MainConfig) GetLogLevel() ldlog.LogLevel

type MetricsConfig

type MetricsConfig struct {
	Datadog     DatadogConfig
	Stackdriver StackdriverConfig
	Prometheus  PrometheusConfig
}

MetricsConfig contains configurations for optional metrics integrations.

This corresponds to the [Datadog], [Stackdriver], and [Prometheus] sections in the configuration file.

type PrometheusConfig

type PrometheusConfig struct {
	Port int
	CommonMetricsConfig
}

PrometheusConfig configures the optional Prometheus integration, which is used only if Enabled is true.

This corresponds to the PrometheusConfig section in the configuration file.

type RedisConfig

type RedisConfig struct {
	Host     string
	Port     int
	Url      string
	LocalTtl int
	Tls      bool
	Password string
}

RedisConfig configures the optional Redis integration, which is used only if Host is non-empty.

This corresponds to the [Redis] section in the configuration file.

type Relay

type Relay struct {
	http.Handler
	// contains filtered or unexported fields
}

Relay relays endpoints to and from the LaunchDarkly service

func NewRelay

func NewRelay(c Config, clientFactory clientFactoryFunc) (*Relay, error)

NewRelay creates a new relay given a configuration and a method to create a client

type StackdriverConfig

type StackdriverConfig struct {
	ProjectID string
	CommonMetricsConfig
}

StackdriverConfig configures the optional Stackdriver integration, which is used only if Enabled is true.

This corresponds to the StackdriverConfig section in the configuration file.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL