{"id":320968,"name":"Spruce","description":"Enrichment pipeline for CUR / FOCUS reports which adds energy and carbon data allowing to report and reduce the impact of the your cloud usage.","url":"https://github.com/digitalpebble/spruce","last_synced_at":"2026-06-03T10:30:19.946Z","repository":{"id":305160376,"uuid":"1021532509","full_name":"DigitalPebble/spruce","owner":"DigitalPebble","description":"SPRUCE is an open-source  enrichment platform for GreenOps which helps measure and reduce the environmental impact of cloud computing.","archived":false,"fork":false,"pushed_at":"2026-05-25T09:10:51.000Z","size":4148,"stargazers_count":21,"open_issues_count":11,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-31T09:02:47.615Z","etag":null,"topics":["apache-spark","aws","carbon-emissions","climate","cloud","greenops","greensoftware","open-source","sustainability"],"latest_commit_sha":null,"homepage":"http://opensourcegreenops.cloud/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DigitalPebble.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"DigitalPebble"}},"created_at":"2025-07-17T14:38:32.000Z","updated_at":"2026-05-26T13:04:41.000Z","dependencies_parsed_at":"2026-03-03T14:00:58.846Z","dependency_job_id":"2341ca28-71e9-43a1-81d1-446068259f9d","html_url":"https://github.com/DigitalPebble/spruce","commit_stats":null,"previous_names":["digitalpebble/spruce"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/DigitalPebble/spruce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalPebble%2Fspruce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalPebble%2Fspruce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalPebble%2Fspruce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalPebble%2Fspruce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DigitalPebble","download_url":"https://codeload.github.com/DigitalPebble/spruce/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalPebble%2Fspruce/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33816488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"owner":{"login":"DigitalPebble","name":"DigitalPebble Ltd","uuid":"1726647","kind":"organization","description":null,"email":"github@digitalpebble.com","website":"http://www.digitalpebble.com","location":"Bristol, UK","twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/1726647?v=4","repositories_count":27,"last_synced_at":"2024-11-24T19:46:52.245Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/DigitalPebble","funding_links":[],"total_stars":1242,"followers":9,"following":0,"created_at":"2022-11-02T21:15:35.203Z","updated_at":"2024-11-24T19:46:52.246Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DigitalPebble","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DigitalPebble/repositories"},"packages":[],"commits":{"id":10593939,"full_name":"digitalpebble/spruce","default_branch":"main","total_commits":406,"total_committers":8,"total_bot_commits":28,"total_bot_committers":2,"mean_commits":50.75,"dds":0.26847290640394084,"past_year_total_commits":405,"past_year_total_committers":8,"past_year_total_bot_commits":28,"past_year_total_bot_committers":2,"past_year_mean_commits":50.625,"past_year_dds":0.2691358024691358,"last_synced_at":"2026-05-31T10:04:36.952Z","last_synced_commit":"2f86ba10bcaaa7f2a9b49a99a367843ba918cf69","created_at":"2025-07-19T00:07:57.325Z","updated_at":"2026-05-31T10:03:55.679Z","committers":[{"name":"Julien Nioche","email":"julien@digitalpebble.com","login":"jnioche","count":297},{"name":"Davide Polato","email":"davide.polato13@gmail.com","login":"davide954","count":64},{"name":"dependabot[bot]","email":"49699333+dependabot[bot]","login":"dependabot[bot]","count":25},{"name":"=","email":"=","login":null,"count":7},{"name":"nikhiln64","email":"nikhiln64@gmail.com","login":"nikhiln64","count":6},{"name":"copilot-swe-agent[bot]","email":"198982749+Copilot","login":"Copilot","count":3},{"name":"Julien","email":"julien.niochegreenpixie.com@Juliens-MacBook-Air.local","login":null,"count":3},{"name":"tejas-2232","email":"tejasbachhav98@gmail.com","login":"tejas-2232","count":1}],"past_year_committers":[{"name":"Julien Nioche","email":"julien@digitalpebble.com","login":"jnioche","count":296},{"name":"Davide Polato","email":"davide.polato13@gmail.com","login":"davide954","count":64},{"name":"dependabot[bot]","email":"49699333+dependabot[bot]","login":"dependabot[bot]","count":25},{"name":"=","email":"=","login":null,"count":7},{"name":"nikhiln64","email":"nikhiln64@gmail.com","login":"nikhiln64","count":6},{"name":"copilot-swe-agent[bot]","email":"198982749+Copilot","login":"Copilot","count":3},{"name":"Julien","email":"julien.niochegreenpixie.com@Juliens-MacBook-Air.local","login":null,"count":3},{"name":"tejas-2232","email":"tejasbachhav98@gmail.com","login":"tejas-2232","count":1}],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalpebble%2Fspruce/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-06-02T00:00:09.939Z","repositories_count":6252971,"commits_count":883940648,"contributors_count":35035670,"owners_count":1162213,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"digitalpebble/spruce","html_url":"https://github.com/digitalpebble/spruce","last_synced_at":"2026-05-31T09:00:31.185Z","status":"active","issues_count":74,"pull_requests_count":67,"avg_time_to_close_issue":1696926.9090909092,"avg_time_to_close_pull_request":110664.85245901639,"issues_closed_count":44,"pull_requests_closed_count":61,"pull_request_authors_count":7,"issue_authors_count":3,"avg_comments_per_issue":1.0405405405405406,"avg_comments_per_pull_request":1.417910447761194,"merged_pull_requests_count":60,"bot_issues_count":0,"bot_pull_requests_count":12,"past_year_issues_count":74,"past_year_pull_requests_count":67,"past_year_avg_time_to_close_issue":1696926.9090909092,"past_year_avg_time_to_close_pull_request":110664.85245901639,"past_year_issues_closed_count":44,"past_year_pull_requests_closed_count":61,"past_year_pull_request_authors_count":7,"past_year_issue_authors_count":3,"past_year_avg_comments_per_issue":1.0405405405405406,"past_year_avg_comments_per_pull_request":1.417910447761194,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":12,"past_year_merged_pull_requests_count":60,"created_at":"2025-07-19T00:07:57.867Z","updated_at":"2026-05-31T09:00:31.185Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalpebble%2Fspruce","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalpebble%2Fspruce/issues","issue_labels_count":{"enhancement":32,"help wanted":12,"good first issue":12,"Azure":8,"documentation":7,"bug":2,"dependencies":2,"docker":1},"pull_request_labels_count":{"enhancement":28,"dependencies":14,"documentation":8,"java":8,"Azure":5,"github_actions":4,"bug":1},"issue_author_associations_count":{"MEMBER":72,"NONE":1,"CONTRIBUTOR":1},"pull_request_author_associations_count":{"MEMBER":44,"CONTRIBUTOR":19,"NONE":3,"COLLABORATOR":1},"issue_authors":{"jnioche":72,"adamwirth":1,"dpol1":1},"pull_request_authors":{"jnioche":44,"dependabot[bot]":12,"dpol1":4,"davide954":3,"nikhiln64":2,"de9uch1":1,"TheSamStewart":1},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-06-02T00:00:10.211Z","repositories_count":14745800,"issues_count":33334858,"pull_requests_count":110023670,"authors_count":11288635,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{"enhancement":32,"help wanted":12,"good first issue":12,"Azure":8,"documentation":7,"dependencies":2,"bug":2,"docker":1},"past_year_pull_request_labels_count":{"enhancement":28,"dependencies":14,"documentation":8,"java":8,"Azure":5,"github_actions":4,"bug":1},"past_year_issue_author_associations_count":{"MEMBER":72,"CONTRIBUTOR":1,"NONE":1},"past_year_pull_request_author_associations_count":{"MEMBER":44,"CONTRIBUTOR":19,"NONE":3,"COLLABORATOR":1},"past_year_issue_authors":{"jnioche":72,"adamwirth":1,"dpol1":1},"past_year_pull_request_authors":{"jnioche":44,"dependabot[bot]":12,"dpol1":4,"davide954":3,"nikhiln64":2,"de9uch1":1,"TheSamStewart":1},"maintainers":[{"login":"jnioche","count":116,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jnioche"},{"login":"de9uch1","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/de9uch1"}],"active_maintainers":[{"login":"jnioche","count":116,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jnioche"},{"login":"de9uch1","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/de9uch1"}]},"events":{"total":{"ReleaseEvent":2,"DeleteEvent":58,"PullRequestEvent":118,"ForkEvent":1,"DiscussionEvent":1,"IssuesEvent":63,"WatchEvent":6,"IssueCommentEvent":50,"PublicEvent":1,"PushEvent":118,"PullRequestReviewCommentEvent":21,"PullRequestReviewEvent":17,"GollumEvent":6,"CreateEvent":51},"last_year":{"ReleaseEvent":2,"DeleteEvent":58,"PullRequestEvent":118,"ForkEvent":1,"DiscussionEvent":1,"IssuesEvent":63,"WatchEvent":6,"IssueCommentEvent":50,"PublicEvent":1,"PushEvent":118,"PullRequestReviewCommentEvent":21,"PullRequestReviewEvent":17,"GollumEvent":6,"CreateEvent":51}},"keywords":["apache-spark","aws","carbon-emissions","climate","cloud","greenops","greensoftware","open-source","sustainability"],"dependencies":[{"ecosystem":"actions","filepath":".github/workflows/docker.yml","sha":null,"kind":"manifest","created_at":"2026-03-03T14:00:57.327Z","updated_at":"2026-03-03T14:00:57.327Z","repository_link":"https://github.com/DigitalPebble/spruce/blob/main/.github/workflows/docker.yml","dependencies":[{"id":25830047014,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v6","direct":true,"kind":"composite","optional":false},{"id":25830047015,"package_name":"docker/login-action","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":25830047016,"package_name":"docker/setup-qemu-action","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":25830047037,"package_name":"docker/setup-buildx-action","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":25830047038,"package_name":"docker/metadata-action","ecosystem":"actions","requirements":"v5","direct":true,"kind":"composite","optional":false},{"id":25830047039,"package_name":"docker/build-push-action","ecosystem":"actions","requirements":"v6","direct":true,"kind":"composite","optional":false},{"id":25830047040,"package_name":"actions/attest-build-provenance","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/documentation.yml","sha":null,"kind":"manifest","created_at":"2026-03-03T14:00:57.726Z","updated_at":"2026-03-03T14:00:57.726Z","repository_link":"https://github.com/DigitalPebble/spruce/blob/main/.github/workflows/documentation.yml","dependencies":[{"id":25830047041,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v6","direct":true,"kind":"composite","optional":false},{"id":25830047042,"package_name":"actions/configure-pages","ecosystem":"actions","requirements":"v5","direct":true,"kind":"composite","optional":false},{"id":25830047043,"package_name":"actions/upload-pages-artifact","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false},{"id":25830047044,"package_name":"actions/deploy-pages","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"pypi","filepath":"requirements-report.txt","sha":null,"kind":"manifest","created_at":"2026-03-03T14:00:58.416Z","updated_at":"2026-03-03T14:00:58.416Z","repository_link":"https://github.com/DigitalPebble/spruce/blob/main/requirements-report.txt","dependencies":[{"id":25830047075,"package_name":"duckdb","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":25830047107,"package_name":"markdown","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":25830047108,"package_name":"weasyprint","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/maven.yml","sha":null,"kind":"manifest","created_at":"2025-07-18T17:52:18.442Z","updated_at":"2025-07-18T17:52:18.442Z","repository_link":"https://github.com/DigitalPebble/spruce/blob/main/.github/workflows/maven.yml","dependencies":[{"id":24199908414,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false},{"id":24199908415,"package_name":"actions/setup-java","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false},{"id":24199908416,"package_name":"advanced-security/maven-dependency-submission-action","ecosystem":"actions","requirements":"571e99aab1055c2e71a1e2309b9691de18d6b7d6","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"docker","filepath":"Dockerfile","sha":null,"kind":"manifest","created_at":"2025-07-18T17:52:18.530Z","updated_at":"2025-07-18T17:52:18.530Z","repository_link":"https://github.com/DigitalPebble/spruce/blob/main/Dockerfile","dependencies":[{"id":24199908417,"package_name":"maven","ecosystem":"docker","requirements":"3.9.9-eclipse-temurin-21","direct":true,"kind":"build","optional":false},{"id":24199908418,"package_name":"apache/spark","ecosystem":"docker","requirements":"4.0.0-java21","direct":true,"kind":"build","optional":false}]},{"ecosystem":"maven","filepath":"pom.xml","sha":null,"kind":"manifest","created_at":"2025-07-18T17:52:18.756Z","updated_at":"2025-07-18T17:52:18.756Z","repository_link":"https://github.com/DigitalPebble/spruce/blob/main/pom.xml","dependencies":[{"id":24199908440,"package_name":"org.apache.spark:spark-sql_2.13","ecosystem":"maven","requirements":"4.0.0","direct":true,"kind":"provided","optional":false},{"id":24199908441,"package_name":"org.junit.jupiter:junit-jupiter-api","ecosystem":"maven","requirements":"5.13.1","direct":true,"kind":"test","optional":false},{"id":24199908442,"package_name":"org.junit.jupiter:junit-jupiter-engine","ecosystem":"maven","requirements":"5.13.1","direct":true,"kind":"test","optional":false}]}],"score":5.545177444479562,"created_at":"2025-07-19T00:07:39.749Z","updated_at":"2026-06-03T10:30:19.948Z","avatar_url":"https://github.com/DigitalPebble.png","language":"Java","category":"Consumption","sub_category":"Computation and Communication","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"\u003cp align=\"center\" width=\"100%\"\u003e\n  \u003cimg src=\"logo.png\" alt=\"Spruce\" width=\"512\"/\u003e\n\u003c/p\u003e\n\n# SPRUCE\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n![Build Status](https://github.com/apache/stormcrawler/actions/workflows/maven.yml/badge.svg)\n\n**SPRUCE** helps estimate the environmental impact of your cloud usage. By leveraging open source models and data, it enriches\nusage reports generated by cloud providers and allows you to build reports and visualisations. Having the GreenOps and FinOps data in the same\nplace makes it easier to expose your costs and impacts side by side.\n\n## Why SPRUCE?\n\nCloud providers do report environmental impact — but at a level of aggregation that makes it impossible to act on. Figures are rolled up at account or service level, cover carbon at best, and sit entirely separate from your cost data. They tell you how you're doing; they don't help you do better.\n\nSPRUCE is built around the idea that actionable GreenOps requires the same granularity as FinOps:\n\n- **Resource-level detail** — identify which workloads, teams, or environments are driving your footprint, not just your bill.\n- **Multiple impact dimensions** — beyond carbon, SPRUCE models water consumption, giving a fuller picture of your cloud's environmental cost.\n- **GreenOps and FinOps together** — cost and impact share the same pipeline, so trade-off decisions are grounded in real data.\n- **Open and auditable** — built on open source models and public data, so your methodology is transparent, not black-boxed.\n- **Your data stays yours** — running on EMR means your CUR data never leaves your AWS environment.\n- **Actively maintained** — unlike Cloud Carbon Footprint, which has been abandoned, SPRUCE is under active development.\n\nSPRUCE handles CUR reports from AWS and partially supports Azure. However, most of the cost from a typical usage already gets estimates.\n\n## How it works\n\n**SPRUCE** uses [Apache Spark®](https://spark.apache.org/) to read and write the usage reports (typically in Parquet format) in a scalable way and, thanks to its modular approach,\nsplits the enrichment of the data into configurable stages.\n\nA typical sequence of stages would be:\n- estimation of embodied emissions from the hardware\n- estimation of energy used\n- estimation of water consumption\n- application of PUE / WUE and other overheads\n- application of carbon intensity factors\n\nHave a look at the [methodology section](https://opensourcegreenops.cloud/methodology.html) of our documentation for more details.\n\n## Documentation \n\nThe documentation is at https://opensourcegreenops.cloud/. If you can't wait to try SPRUCE, have a look at the [tutorial for Docker](https://opensourcegreenops.cloud/tutorial/with-docker.html).\n\nTo explore enriched output, see\n[Explore the results](https://opensourcegreenops.cloud/tutorial/results.html)\nand [Build a simple dashboard](https://opensourcegreenops.cloud/howto/dashboard.html).\n\n## License\nLicensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0\n\n## Contributing\nWe welcome contributions to the project, see [CONTRIBUTING.md](CONTRIBUTING.md) for instructions on how to do so. Contributions are not only about code: by testing the project on your data, talking about it or asking questions, you will be contributing too!\n\n## Support\nDo you need help with SPRUCE? Want some bespoke work, training or a workshop? We at [DigitalPebble](https://digitalpebble.com/), provide consulting services for SPRUCE. \nSend us an email at _spruce@digitalpebble.com_!\n\n","funding_links":["https://github.com/sponsors/DigitalPebble"],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":[],"project_url":"https://ost.ecosyste.ms/api/v1/projects/320968","html_url":"https://ost.ecosyste.ms/projects/320968"}