Skip to main content

GreenFrame CLI

The GreenFrame CLI is a standalone command that can run an analysis, collect system metrics, and turn them into carbon footprint estimates. It is an open-source project hosted on GitHub at marmelab/greenframe-cli and used internally by the greenframe.io website.

Installation

To install the GreenFrame CLI, type the following command in your favorite terminal:

curl https://assets.greenframe.io/install.sh | bash

To verify that GreenFrame CLI has correctly been installed, type:

$ greenframe -v
enterprise-cli/1.2.2 linux-x64 node-v16.14.0
info

The GreenFrame CLI requires Docker to be installed.

Usage

To estimate the energy consumption and carbon emissions of a visit to a public web page, call greenframe analyze with the URL of the page you want to analyze:

$ greenframe analyze https://marmelab.com

The greenframe analyze command launches a headless browser locally, and visits the URL passed as an argument. It records the CPU activity, the network traffic, the memory footprint, and the time taken to complete the visit. This command runs the analysis 3 times to get a more accurate value.

The command then prints the results in the terminal:

$ greenframe analyze https://marmelab.com
✅ main scenario completed
The estimated footprint is 0.038 g eq. co2 ± 10.3% (0.085 Wh).
info

Type greenframe help if you are lost!

Custom Scenario

You can run a custom scenario instead of the "visit" scenario by passing a scenario file to the analyze command:

$ greenframe analyze https://marmelab.com ./my-scenario.js

GreenFrame uses PlayWright to run scenarios. A custom PlayWright scenario looks like the following:

// in my-scenario.js
const visit = async (page) => {
await page.goto('', { waitUntil: 'networkidle' }); // Go to the baseUrl
await page.waitForTimeout(3000); // Wait for 3 seconds
await page.scrollToElement('footer'); // Scroll to the footer (if present)
await page.waitForNetworkIdle(); // Wait every request has been answered as a normal user.
};

module.exports = visit;

Check the Writing a scenario page for more details.

Testing A Scenario

You can test your scenario using the greenframe open command. It uses the local Chrome browser to run the scenario:

$ greenframe open https://marmelab.com ./my-scenario.js

A Chromium or Google chrome browser is required to execute this command correctly. If it's not installed, type the following command:

$ sudo apt-get install chromium-browser

Full-Stack Analysis

You can monitor the energy consumption of other docker containers while running the scenario. This allows for spawning an entire infrastructure and monitoring the energy consumption of the whole stack.

For instance, if you start a set of docker containers using docker-compose, containing the following services:

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d94f1c458c19 node:16 "docker-entrypoint.s…" 7 seconds ago Up 7 seconds 0.0.0.0:3003->3000/tcp enterprise_app
f024c10e666b node:16 "docker-entrypoint.s…" 7 seconds ago Up 7 seconds 0.0.0.0:3006->3006/tcp enterprise_api
b6b5f8eb9a6d postgres:13 "docker-entrypoint.s…" 8 seconds ago Up 8 seconds 0.0.0.0:5434->5432/tcp enterprise_db

You can run an analysis on the full stack (the browser + the 3 server containers) by passing the --containers and --databaseContainers options:

$ greenframe analyze https://localhost:3000/ ./my-scenario.js --containers="enterprise_app,enterprise_api" --databaseContainers="enterprise_db"

GreenFrame needs to identify database containers because it computes the impact of network I/O differently between the client and the server, and within the server infrastructure.

For more details, check the full-stack analysis documentation.

Using An Ad Blocker

Third-party tags can be a significant source of energy consumption. When you use the --useAdblock option, GreenFrame uses an Ad Blocker to let you estimate that cost.

Run two analyses, a normal one then an ad-blocked one, and compare the results:

$ greenframe analyze https://adweek.com
The estimated footprint is 0.049 g eq. co2 ± 1% (0.112 Wh).
$ greenframe analyze https://adweek.com --useAdblock
The estimated footprint is 0.028 g eq. co2 ± 1.1% (0.063 Wh).

In this example, the cost of ads and analytics is 0.049g - 0.028g = 0.021g eq. co2 (42% of the total footprint).

Defining A Threshold

The greenframe analyze command measures the footprint of a scenario, but doesn't make any decision to determine whether the footprint is good or bad.

You can decide that any analysis with a footprint above a certain threshold is considered a failure, and any analysis below that threshold is considered a success. This is especially useful when using GreenFrame in a CI environment, where you want to make sure that a change in the code doesn't increase the energy consumption of your scenario.

Use the threshold option to set maximum carbon emissions in g eq. co2 for a successful return (exit 0).

$ greenframe analyze https://cnn.com --threshold=0.045
❌ main scenario failed
The estimated footprint at 0.05 g eq. co2 ± 1.3% (0.114 Wh) passes the limit configured at 0.045 g eq. co2.

In case of failed analysis, the CLI exits with exit code 1.

Syncing With GreenFrame.io

If you want to get more insights about your carbon footprint, you can sync your analysis with GreenFrame.io. This service provides:

  • A dashboard to monitor your carbon footprint over time
  • A detailed analysis of your carbon footprint, with a breakdown by scenario, container, scenario step, and component
  • A comparison with previous analyses on the main branch (for Pull Request analysis)

image

To get started, subscribe to GreenFrame.io and create a new project. Then, get your token from the greenframe project page. Pass this token to each greenframe command using the GREENFRAME_SECRET_TOKEN environment variable:

$ GREENFRAME_SECRET_TOKEN=your-token-here greenframe analyze https://marmelab.com
✅ main scenario completed
The estimated footprint is 0.038 g eq. co2 ± 9.6% (0.086 Wh).
Check the details of your analysis at https://app.greenframe.io/analyses/7d7b7777-600c-4399-842f-b70db9408f53

When using a greenframe.io token, the greenframe analyze command generates an online report at https://app.greenframe.io/YOUR_ANALYSIS_ID with much more details than the estimated footprint, and outputs its URL on the console.

Alternatively, you can export this environment variable in your shell configuration file (.bashrc, .zshrc, etc.).

export GREENFRAME_SECRET_TOKEN=your-token-here

Using a Configuration File

Instead of passing all options on the command line, you can use a configuration file. Create a .greenframe.yml file in the root of your project:

baseURL: YOUR_APP_BASE_URL
scenarios:
- path: PATH_TO_YOUR_SCENARIO_FILE
name: My first scenario
threshold: 0.1
projectName: YOUR_PROJECT_NAME
samples: 3
useAdblock: true
containers:
- 'CONTAINER_NAME'
- 'ANOTHER_CONTAINER_NAME'
databaseContainers:
- 'DATABASE_CONTAINER_NAME',
envFile: PATH_TO_YOUR_ENVIRONMENT_VAR_FILE
envVar:
- envVarA: 'An environment variable needed for the scenario (ie : a secret-key)',
- envVarB: 'Another environment variable needed'

Then in the same folder, GreenFrame CLI will automatically take the configuration file.

Check the configuration file reference for more details.

Improving The Analysis Precision

GreenFrame computes the precision of your analysis by comparing the footprint across several samples. By default, GreenFrame runs your scenario three times.

A good precision should be less than 2%. If your analyses have a precision score greater than 2%, this will make the detection of changes in the footprint harder - as a 2% change may not be significant.

There are several ways to improve the precision of your analysis:

  1. Avoid pages with variable content in your scenarios. For instance, a page that loads a random wallpaper will have a variable footprint on every analysis. Run your scenarios on a fixed data set instead.
  2. Use a longer scenario: As the analysis score depends on the duration of the scenario, the longer it takes to run a scenario, the better the precision. Try to aim for a scenario of at least 10 seconds.
  3. Increase the number of samples: Add the samples: [nb] option to execute the scenario more than three times, e.g. samples: 5
  4. Run the analysis on a server that has stable load (preferably not a CI container) or on the GreenFrame cloud (see below).

Using Kubernetes

GreenFrame can perform an analysis on a Kubernetes cluster. To do so, you need to add some specific configuration to your .greenframe.yml file.

//...
kubeContainers:
- "demo:name=app"
kubeDatabaseContainers:
- "demo:name=db"
kubeConfig: "/path/to/kube/config"

Check the configuration file reference for more details.

Once your configuration file is set up, you need to configure your kubernetes cluster to allow Greenframe to perform an analysis. To do so, run :

$ greenframe kube-config

This command will deploy a cadvisor daemonset on your cluster. This daemonset collects stats and exposes them to greenframe.

Greenframe daemonset architecture

You are now ready to perform your first k8s analysis.

info

Even if we analyze an application running on a kubernetes cluster, the execution of the scenario is still using Docker (to launch the headless browser). That means the server on which the analysis is launched must have Docker installed.

CLI Reference

analyze

You can directly pass options as analyze command parameters to override how your analysis will be performed.

Using One Line Command

If for some reason you don't want to perform an analysis by using a .greenframe.yml you can specify the baseURL of your project and the path to your scenario file directly in one command:

Example: greenframe analyze http://localhost:3000 scenario.js

info

Please note by using one line command, you can't run multiple scenarios.

--projectName Option

To follow the evolution of your analysis made on GreenFrame, use --projectName or -p to identify your project in GreenFrame.

The project name can be passed as the GREENFRAME_PROJECT_NAME environment variable in the CI environment.

If the project name is not specified through the command option or the environment variable, GreenFrame will automatically retrieve your git's project name and use it as the project name. Please note that the command must be executed in the corresponding git project for this to work.

Example: greenframe analyze http://localhost:3000 scenario.js --projectName my_awesome_project

--threshold Option

When using greenframe analyze in a CI environment, you typically want the build to fail if the carbon footprint exceeds a predefined threshold in g eq. co2. Use the --threshold option (or -t) for that.

Example : greenframe analyze http://localhost:3000 scenario.js --threshold 0.05

--commitMessage Option

When using greenframe analyze in a CI environment, you want to know for which commit GreenFrame made an analysis. GreenFrame CLI automatically retrieves it but in some CI you can't have access to .git folder and this detection will fail. You can pass it and override the commit message detection by using the --commitMessage option (or -c).

Example: greenframe analyze http://localhost:3000 scenario.js --commitMessage "Add login feature"

--commitId Option

When using greenframe analyze in a CI environment, you want to know for which commit GreenFrame made an analysis. GreenFrame CLI automatically retrieves it but in some CI you can't have access to .git folder and this detection will fail. You can pass it and override the commit ID detection by using the --commitId option.

Example : greenframe analyze http://localhost:3000 scenario.js --commitId "SHA1_COMMIT_ID"

info

Please note if this variable is not set, you will not be able to perform automatic comparison with your default git branch. This git branch can be configured per project inside your settings directly in the application.

--branchName Option

When using greenframe analyze in a CI environment, you want to know for which branch GreenFrame made an analysis. GreenFrame CLI automatically retrieves it but in some CI you can't have access to .git folder and this detection will fail. You can pass it and override the branch name detection by using the --branchName option (or -b).

Example: greenframe analyze http://localhost:3000 scenario.js --branchName "feat/login"

--samples Option

When using greenframe analyze in a CI environment, you might want to change the number of samples that are performed by the analysis in order to improve the precision. Use the --samples option (or -s). Its default value is 3.

Example : greenframe analyze http://localhost:3000 scenario.js --samples 5

--useAdblock Option

Analyzing an app containing third-party scripts (ads or trackers) can encounter errors or slow down the analysis due to the weight of these scripts. You can these third-party scripts by using the embedded adblocker.

Example : greenframe analyze http://localhost:3000 scenario.js --useAdblock

info

Please take into account that we use a predefined list of third-party scripts to block. It's possible that your ads or tracker will not be blocked.

--configFile Option

If your configuration file is located to another path or is named differently than .greenframe.yml, you can provide a path to this file by using the --configFile or -C argument.

Example: greenframe analyze --configFile ./config/mygreenframefile.yml

--dockerdHost Option

If you need to specify a specific docker host, you can use the dockerdHost option.

--dockerdPort Option

If you need to specify a specific docker port, you can use the dockerdPort option.

--envFile Option

If you need to use some environment variables in your scenarios, you can use the envFile option (Can be used in addition to envVar).

In this env file, you can have either couples of variables/values or only variables. When no value is specified, the runner assume that the environment variable exists in the execution context.

.envFile
ENV_VAR_LOGIN=myLogin
ENV_VAR_PASSWORD

--envVar Option

If you need to use some environment variables in your scenarios, you can use the envVar option (Can be used in addition to envFile).

You can enter a mix of couple of variables/values or only variables. When no value is specified, the runner assume that the environment variable exists in the execution context.

Example: greenframe analyze --envVar ENV_VAR_PASSWORD --envVar ENV_VAR_LOGIN=luke www.myWebsite.com

kube-config

This command is Kubernetes-specific and helps configure the cluster to let Greenframe monitor its activity and perform an analysis.

--configFile Option

If your configuration file is different from ./.greenframe.yml, you can provide a path to this file by using the --configFile or -C argument.

Example: greenframe analyze --configFile ./config/mygreenframefile.yml

--delete Option

If you want to delete the Greenframe daemonset from your cluster, you can use the --delete or -D option.

Example: greenframe kube-config --delete

--kubeConfig Option

If you need to specify a specific kube config, you can use the kubeConfig of -K option.

Example: greenframe kube-config --kubeConfig ~/.kube/config.staging