{"id":15402255,"url":"https://github.com/mirkosertic/flight-recorder-starter","last_synced_at":"2026-02-20T15:01:32.540Z","repository":{"id":39973237,"uuid":"292393892","full_name":"mirkosertic/flight-recorder-starter","owner":"mirkosertic","description":"This is a Spring Boot 2/3 Starter exposing the JDK Flight Recorder as a Spring Boot Actuator Endpoint.","archived":false,"fork":false,"pushed_at":"2024-04-19T09:42:50.000Z","size":562,"stargazers_count":43,"open_issues_count":12,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T04:12:36.616Z","etag":null,"topics":["actuator","container-management","flamegraph","java","java-flight-recorder","java-mission-control","jdk-flight-recorder","jdk-mission-control","jmc","spring-boot"],"latest_commit_sha":null,"homepage":"","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/mirkosertic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2020-09-02T21:02:21.000Z","updated_at":"2025-03-17T16:45:52.000Z","dependencies_parsed_at":"2023-02-02T09:46:45.704Z","dependency_job_id":"e2e20832-0408-4fa5-85fe-eeb7934e46b5","html_url":"https://github.com/mirkosertic/flight-recorder-starter","commit_stats":{"total_commits":120,"total_committers":6,"mean_commits":20.0,"dds":0.5333333333333333,"last_synced_commit":"c47fe6f31fc2f684c0748bdd314ce9acef80ea25"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mirkosertic%2Fflight-recorder-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mirkosertic%2Fflight-recorder-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mirkosertic%2Fflight-recorder-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mirkosertic%2Fflight-recorder-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mirkosertic","download_url":"https://codeload.github.com/mirkosertic/flight-recorder-starter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249184629,"owners_count":21226422,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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"}},"keywords":["actuator","container-management","flamegraph","java","java-flight-recorder","java-mission-control","jdk-flight-recorder","jdk-mission-control","jmc","spring-boot"],"created_at":"2024-10-01T16:02:15.059Z","updated_at":"2026-02-20T15:01:32.527Z","avatar_url":"https://github.com/mirkosertic.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Why \u0026 When\n\n![Build Workflow](https://github.com/mirkosertic/flight-recorder-starter/workflows/Build%20Workflow/badge.svg) [![Maven Central](https://maven-badges.sml.io/sonatype-central/de.mirkosertic/flight-recorder-starter/badge.svg?style=plastic)](https://maven-badges.sml.io/sonatype-central/de.mirkosertic/flight-recorder-starter)\n\nThis is a Spring Boot Starter exposing the JDK Flight Recorder as a Spring Boot Actuator Endpoint.\n\nNormally the JDK Flight Recorder is available locally or by JMX remote. Depending on your deployment scenario shell or\nJMX access might not be available for the application server. Here comes this handy starter into play!\n\n# How\n\nThis starter adds a new Spring Boot Actuator endpoint for JDK Flight Recorder remote control. This RESTful endpoint\nallows starting and stopping Flight Recording and downloading the `.jfr` files for further analysis.\n\n## Spring Boot 4\n\nAdd the following dependency to your Spring Boot 3 project:\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ede.mirkosertic\u003c/groupId\u003e\n    \u003cartifactId\u003eflight-recorder-starter\u003c/artifactId\u003e\n    \u003cversion\u003e4.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Spring Boot 3\n\nAdd the following dependency to your Spring Boot 3 project:\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ede.mirkosertic\u003c/groupId\u003e\n    \u003cartifactId\u003eflight-recorder-starter\u003c/artifactId\u003e\n    \u003cversion\u003e3.5.6\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Spring Boot 2 (no longer maintained)\n\nAdd the following dependency to your Spring Boot 2 project:\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ede.mirkosertic\u003c/groupId\u003e\n    \u003cartifactId\u003eflight-recorder-starter\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Required for all Spring Boot versions\n\nPlease don't forget to add the following configuration:\n\n```yml\nflightrecorder:\n  enabled: true  # is this starter active?\n``` \n\nIMPORTANT: By default, this starter doesn't include spring webmvc or spring webflux dependencies. You will have to\ninclude them according the stack you wish.\n\n**WebMvc**\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-starter-web\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\n* Please use spring-boot-starter-webmvc for Spring Boot \u003e= 4\n\n**WebFlux**\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-starter-webflux\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\nPlease note: the minimum Java/JVM runtime version is 11!\n\n## Starting Flight Recording\n\nThe following `cURL` command starts a new Flight Recording and returns the created Flight Recording ID:\n\n``` shell\ncurl  -i -X POST -H \"Content-Type: application/json\" -d '{\"duration\": \"60\",\"timeUnit\":\"SECONDS\"}' http://localhost:8080/actuator/flightrecorder/\n\nHTTP/1.1 201 \nLocation: http://localhost:8080/actuator/flightrecorder/1\nContent-Length: 0\nDate: Fri, 05 Feb 2021 12:37:07 GMT\n\n```\n\nFlight Recording starts for a given period, in this case 60 seconds and stops then.\n\nEvery recording session gets its own unique Flight Recording ID. The endpoint returns this ID as plain text, in this\ncase ID `1`. This ID must be used to download the recorded data.\n\n### Advanced commands\n\nIn order to cover more recording options, the payload sent can be composed by different params. Following the whole list\nof params:\n\n| Field Key | Value Type | Mandatory | Description |\n| ------------- |-------------| :-----: | --------|\n| description | String | NO | The description for the recording |\n| duration |  Number | YES  | The duration of recording  |\n| timeUnit |  Serialized ChronoUnit value | YES  | The unit for duration param  |\n| maxAgeDuration  | Number  | NO  | The max age of data you can preserve  |\n| maxAgeUnit  | Serialized ChronoUnit value  | NO  | The unit for maxAge param  |\n| delayDuration  | Number  | NO  | Schedule the recording  |\n| delayUnit  |  Serialized ChronoUnit value | NO  | The unit for delay param  |\n| maxSize | Number  | NO  | Max size of file (in bytes)  |\n| customSettings | JSON Object with N fields  | NO  | JSON object with custom properties that will override the properties in the base configuration  |\n\nMore info at JFR Javadoc [here](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jfr/jdk/jfr/Recording.html).\n\nExample of JSON param:\n\n```json\n{\n  \"description\": \"MyFirstRecording\",\n  \"duration\": \"60\",\n  \"timeUnit\": \"Seconds\",\n  \"maxAgeDuration\": \"10\",\n  \"maxAgeUnit\": \"Seconds\",\n  \"delayDuration\": \"5\",\n  \"delayUnit\": \"Seconds\",\n  \"maxSize\": \"100000\",\n  \"customSettings\": {\n    \"myCustomProperty1\": \"myCustomValue1\",\n    \"myCustomProperty2\": \"myCustomValue2\"\n  }\n}\n```\n\n## Downloading results\n\nThe following `cURL` command stops the Flight Recording with ID `1` and downloads the `.jfr` file:\n\n```shell\ncurl --output recording.jfr http://localhost:8080/actuator/flightrecorder/1\n```\n\nThe downloaded `.jfr` file can be imported into JDK Mission Control (JMC) for further analysis.\n\n## Visiting the interactive Flamegraph\n\nThis starter can generate an interactive Flamegraph from a Flight Recorder recording. You can gain a quick overview by\nvisiting the following URL in your browser to see the graph for a recording with ID `1`:\n\n```\nhttp://localhost:8080/actuator/flightrecorder/ui/1/flamegraph.html\n```\n\nand you'll get:\n\n![Flamegraph](docs/flamegraph.png)\n\nThe starter automatically tries to visualize only classes belonging to the running Spring Boot application. It filters\nthe stacktrace samples by classes that are in the package or sub-package of the running application instance annotated\nwith a\n`@SpringBootApplication` annotation.\n\nHowever, you can always get the unfiltered Flamegraph by visiting:\n\n```\nhttp://localhost:8080/actuator/flightrecorder/ui/1/rawflamegraph.html\n```\n\n## Stopping Flight Recording\n\nThe following `cURL` command stops the Flight Recording with ID `1`.\n\n```shell\ncurl -i -X PUT http://localhost:8080/actuator/flightrecorder/1\n\n\nHTTP/1.1 200\nContent-Type: application/json\nTransfer-Encoding: chunked\nDate: Fri, 05 Feb 2021 12:39:43 GMT\n\n{\"id\":1,\"startedAt\":\"2021-02-05 13:37:08\",\"status\":\"CLOSED\",\"finishedAt\":\"2021-02-05 13:39:43\",\"description\":null}\n\n```\n\n## Delete Flight Recording\n\nThe following `cURL` command stops the Flight Recording with ID `1`.\n\n```shell\ncurl -i -X DELETE http://localhost:8080/actuator/flightrecorder/1\n\nHTTP/1.1 204 \nDate: Fri, 05 Feb 2021 12:40:13 GMT\n\n```\n\nLater, this recording might be deleted in memory and physically by the scheduler process described below.\n\n### Auto-deletion process\n\nIMPORTANT: Be aware that the main app should be annotated with @EnableScheduling to enable the scheduled processes for auto-deletion.\n\nThe process periodically deletes recording files, which are in status `STOPPED` or `CLOSED`. The cleanup interval can be configured via\n\n```properties\nflightrecorder.recording-cleanup-interval=5000\n```\n\nwith default value set on 5000ms. The base unit is MILLISECONDS. Take into account that the deletion is permanently.\n\nThe watermark used to annotate a recording as \"removable\" is either time-based (TTL) or count-based (COUNT).\n\nThe default cleanup type is `TTL` and can be changed using the property:\n```properties\nflightrecorder.recording-cleanup-type=COUNT\n```\n\n#### Deletion by TTL\n\nIf the cleanup type is `TTL` (time to live), the recording's start time represents the reference point for the TTL deletion. The threshold can be configured via the properties below (default: 1 Hour):\n\n```properties\nflightrecorder.old-recordings-TTL=1\nflightrecorder.old-recordings-TTL-time-unit=Hours  # java.time.temporal.ChronoUnit available values\n```\n\nA file will be removed when the status is `STOPPED` or `CLOSED`, and the recording's start time is before _now_ minus _threshold configured_.\n\n#### Deletion by COUNT\n\nIf the cleanup type is `COUNT`, the oldest recordings will be deleted when the total number of existing recordings surpasses the configured threshold of recordings to keep. The threshold can be configured via the property below (default: 10 recordings):\n\n```properties\nflightrecorder.old-recordings-max=10\n```\n\nA file will be removed when the status is `STOPPED` or `CLOSED`, based on a FIFO logic.\n\n\n## Trigger Flight Recording based on Micrometer Metrics\n\nThis starter allows automatic Flight Recording based on Micrometer Metrics. Using an application configuration file we\ncan configure triggers based on SpEL (Spring Expression Language) which are evaluated on a regular basis. Once a trigger\nexpression evaluates to true, a Flight Recording in started with a predefined duration and configuration. The most\ncommon setup would be to trigger a Flight Recording profiling once CPU usage is above a given value.\n\nBy default, this feature is enabled. In case you want to disable it, set the following property to `false`:\n\n```properties\nflightrecorder.trigger-enabled=false\n```\n\nThis scheduled process is executed each 10 seconds. The default configuration can be changed thought this property:\n\n```properties\nflightrecorder.trigger-check-interval=10000\n```\n\nBy default, this scheduled process is executed each 10 seconds. The default configuration can be changed thought this\nproperty:\n\n```properties\nflightrecorder.trigger-check-interval=10000\n```\n\nIMPORTANT: Be aware that the main app should be annotated with @EnableScheduling to enable the scheduled processes.\n\nHere is a sample configuration file in YAML syntax:\n\n```yml\nflightrecorder:\n  enabled: true  # is this starter active?\n  recording-cleanup-interval: 5000 # try to cleanup old recordings every 5 seconds\n  trigger-check-interval: 10000 # evaluate trigger expressions every 10 seconds\n  trigger:\n    - expression: meter('jvm.memory.used').tag('area','nonheap').tag('id','Metaspace').measurement('value') \u003e 100\n      startRecordingCommand:\n        duration: 60\n        timeUnit: Seconds\n``` \n\nThe list of all created recordings can be seen as a JSON file using the following api:\n\n```\nhttp://localhost:8080/actuator/flightrecorder/\n```\n\n## Advanced Configuration\n\n### Location of recordings\n\nBy default, all the recording files are stored at temporal system folder, ofter the \"/tmp\" folder. This base path can be\nchanged through the following property:\n\n```yml\nflightrecorder:\n  jfr-base-path: /my-path \n```\n\n### Custom configuration profile for recordings\n\nBy default, the used configuration is \"_\u003c\u003cJAVA_HOME\u003e\u003e/lib/jfr/profile.jfc_\". A custom configuration can be changed\nthrough the following property:\n\n```yml\nflightrecorder:\n  jfr-custom-config: mycustomjfc \n```\n\n**NOTE**: Just only the file's name (without extension) is required, not whole path.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmirkosertic%2Fflight-recorder-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmirkosertic%2Fflight-recorder-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmirkosertic%2Fflight-recorder-starter/lists"}