{"id":13701945,"url":"https://github.com/mrwilson/byte-monkey","last_synced_at":"2025-12-30T00:14:07.490Z","repository":{"id":41407045,"uuid":"59861017","full_name":"mrwilson/byte-monkey","owner":"mrwilson","description":":monkey: Bytecode-level fault injection for the JVM.","archived":false,"fork":false,"pushed_at":"2020-10-13T06:42:59.000Z","size":120,"stargazers_count":225,"open_issues_count":2,"forks_count":18,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-11-13T09:40:17.881Z","etag":null,"topics":["chaos-engineering","chaos-monkey","java"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrwilson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-27T20:19:00.000Z","updated_at":"2024-09-28T12:57:56.000Z","dependencies_parsed_at":"2022-08-27T06:41:01.809Z","dependency_job_id":null,"html_url":"https://github.com/mrwilson/byte-monkey","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrwilson%2Fbyte-monkey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrwilson%2Fbyte-monkey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrwilson%2Fbyte-monkey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrwilson%2Fbyte-monkey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrwilson","download_url":"https://codeload.github.com/mrwilson/byte-monkey/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252439358,"owners_count":21747992,"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":["chaos-engineering","chaos-monkey","java"],"created_at":"2024-08-02T21:00:28.083Z","updated_at":"2025-12-30T00:14:07.461Z","avatar_url":"https://github.com/mrwilson.png","language":"Java","readme":"# byte-monkey\n\n[![Build Status](https://travis-ci.org/mrwilson/byte-monkey.svg?branch=master)](https://travis-ci.org/mrwilson/byte-monkey)\n[![Coverage Status](https://coveralls.io/repos/github/mrwilson/byte-monkey/badge.svg?branch=master)](https://coveralls.io/github/mrwilson/byte-monkey?branch=master)\n\nByte-Monkey is a small Java library for testing failure scenarios in JVM applications - it works by instrumenting application code on the fly to deliberately introduce faults like exceptions and latency. Original blogpost [here](http://blog.probablyfine.co.uk/2016/05/30/announcing-byte-monkey.html).\n\n\n## Download\n\nLatest version: [1.0.0](https://github.com/mrwilson/byte-monkey/releases/download/1.0.0/byte-monkey.jar)\n\n## How to use\n\n```bash\njava -javaagent:byte-monkey.jar -jar your-java-app.jar\n```\n\n## Supported Modes\n\n * **Fault**: Throw exceptions from methods that declare those exceptions\n * **Latency**: Introduce latency on method-calls\n * **Nullify**: Replace the first non-primitive argument to the method with *null*\n * **Short-circuit**: Throw corresponding exceptions at the very beginning of try blocks\n\n## Options\n\n * `mode`: What mode to run in - currently supports `fault`, `latency`, `nullify`, and `scircuit`. **Default is fault**\n * `rate`: Value between 0 and 1 - how often to activate the fault. **Default is 1, i.e. 100%**\n * `filter`: Only instrument packages or methods matching the (java-style) regex. **Default is .*, i.e. all methods**\n \nbyte-monkey is configured with a comma-separated key-value pair string of the options as the agent argument.\n\n```bash\njava -javaagent:byte-monkey.jar=mode:fault,rate:0.5,filter:uk/co/probablyfine/ -jar your-java-app.jar\n```\n\nThe example above would run in fault mode, activating on 50% of eligible method calls, for anything in the package tree below `uk.co.probablyfine`\n\n## Modes\n\n### Fault\n\nRunning byte-monkey in `fault` mode will cause the first declared exception in a method signature to be thrown.\n\n**CAVEAT**: Byte-Monkey can only create Exceptions that expose a public default constructor as a result of how it instantiates them. If such a constructor doesn't exist, it falls back to a `ByteMonkeyException` instead.\n\n### Latency\n\nRunning byte-monkey in `latency` mode will cause the method to sleep before executing further instructions.\n\nThere is a configuration option available only during this mode:\n\n * `latency`: Duration (in millis) to wait on method calls, only valid when running in **Latency** mode. **Default is 100ms**\n\nExample: `java -javaagent:byte-monkey.jar=mode:latency,rate:0.5,latency:150 -jar your-java-app.jar`\n\n### Nullify\n\nRunning byte-monkey in `nullify` mode will replace the first non-primitive argument to the method call with a null value.\n\nMethods with only primitive arguments or no arguments at all will not be affected by the agent in this mode.\n\n### Short-circuit\n\nRunning byte-monkey in `scircuit` mode will throw corresponding exceptions in the very beginning of try blocks.\n\nThere is a configuration option available only during this mode:\n\n * `tcindex`: Index of which exception to throw when there are multiple catch blocks, e.g. `tcindex=0` indicates the first type of exception in the catch block. Only valid when running in **Short-circuit** mode. **Default is -1/first**\n\nExample:\n```bash\njava -javaagent:byte-monkey.jar=mode:scircuit,filter:package/path/ClassName/MethodName,tcindex=0 -jar your-java-app.jar\n```\n\nYou can read [this paper](https://hal.inria.fr/hal-01062969/document) or [this blog](http://blog.gluckzhang.com/archives/107/) for more information about short-circuit testing.\n\n## Implementation Details\n\nByte-Monkey uses the JVM [Instrumentation API](https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html). Implementing the API enables you to register transformers that can iterate over (and transform) class files as they are loaded by the JVM. Byte-Monkey uses [Objectweb ASM](http://asm.ow2.org/) which comes packaged with the JDK to chance the underlying bytecode of loaded classes\n\n### Injecting Failure\n\nThe bytecode of a simple \"Hello, World!\" method prior to having an exception injected looks like this:\n\n```\n  public void printSomething() throws java.io.IOException;\n    Code:\n       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;\n       3: ldc           #3                  // String Hello!\n       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V\n       8: return\n```\n\nAfter being transformed by the Byte-Monkey, it instead looks like this:\n```\n  public void printSomething() throws java.io.IOException;\n    Code:\n       0: ldc2_w        #18                 // double 0.5d\n       3: invokestatic  #25                 // Method uk/co/probablyfine/bytemonkey/AddChanceOfFailure.shouldActivate:(D)Z\n       6: ifeq          15\n       9: ldc           #26                 // String java/io/IOException\n      11: invokestatic  #32                 // Method uk/co/probablyfine/bytemonkey/CreateAndThrowException.throwOrDefault:(Ljava/lang/String;)Ljava/lang/Throwable;\n      14: athrow\n      15: getstatic     #38                 // Field java/lang/System.out:Ljava/io/PrintStream;\n      18: ldc           #40                 // String Hello!\n      20: invokevirtual #46                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V\n      23: return\n```\n\nThis is the core of how Byte-Monkey works:\n\n * **0:** Load the failure injection rate onto the stack\n * **3:** A call to `AddChanceOfFailure.shouldActivate` which returns true/false depending on the rate\n * **6:** If `shouldActivate` was false, we jump straight to instruction 15 - the beginning of the original code.\n * **9:** Load the name of the exception that would be thrown (here an IOException)\n * **11:** Create the exception if it has a default constructor, or create a wrapper exception\n * **14:** Throw the exception\n\nFor modes other than `fault`, instructions 9 to 14 are replaced with mode-specific instructions.","funding_links":[],"categories":["Notable Tools","容错组件","3. Fault Injection"],"sub_categories":["Languages"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrwilson%2Fbyte-monkey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrwilson%2Fbyte-monkey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrwilson%2Fbyte-monkey/lists"}