## File: README.md [](https://coveralls.io/github/moleculerjs/moleculer?branch=master) [](https://codeclimate.com/github/moleculerjs/moleculer/maintainability) [](https://www.codacy.com/gh/moleculerjs/moleculer/dashboard?utm_source=github.com&utm_medium=referral&utm_content=moleculerjs/moleculer&utm_campaign=Badge_Grade) [](https://snyk.io/test/github/moleculerjs/moleculer) [](https://discord.gg/TSEcDRP) [](https://gurubase.io/g/moleculer) [](https://www.npmjs.com/package/moleculer) [][patreon] # Moleculer [](https://www.npmjs.com/package/moleculer) [](https://twitter.com/intent/tweet?text=Moleculer%20is%20a%20modern%20microservices%20framework%20for%20Node.js&url=https://github.com/moleculerjs/moleculer&via=MoleculerJS&hashtags=nodejs,javascript,microservices) Moleculer is a fast, modern and powerful microservices framework for [Node.js](https://nodejs.org/en/). It helps you to build efficient, reliable & scalable services. Moleculer provides many features for building and managing your microservices. **Website**: [https://moleculer.services](https://moleculer.services) **Documentation**: [https://moleculer.services/docs](https://moleculer.services/docs) # Top sponsors | [](https://www.servereye.de/) | | --- | # What's included - Promise-based solution (async/await compatible) - request-reply concept - support event driven architecture with balancing - built-in service registry & dynamic service discovery - load balanced requests & events (round-robin, random, cpu-usage, latency, sharding) - many fault tolerance features (Circuit Breaker, Bulkhead, Retry, Timeout, Fallback) - plugin/middleware system - support versioned services - support [Streams](https://nodejs.org/docs/latest/api/stream.html) - service mixins - built-in caching solution (Memory, MemoryLRU, Redis) - pluggable loggers (Console, File, Pino, Bunyan, Winston, Debug, Datadog, Log4js) - pluggable transporters (TCP, NATS, MQTT, Redis, Kafka, AMQP 0.9, AMQP 1.0) - pluggable serializers (JSON, JSONExt, MsgPack, CBOR, Notepack) - pluggable parameter validator - multiple services on a node/server - master-less architecture, all nodes are equal - built-in parameter validation with [fastest-validator](https://github.com/icebob/fastest-validator) - built-in metrics feature with reporters (Console, CSV, Datadog, Event, Prometheus, StatsD) - built-in tracing feature with exporters (Console, Datadog, Event, Jaeger, Zipkin, NewRelic) - official [API gateway](https://github.com/moleculerjs/moleculer-web), [Database access](https://github.com/moleculerjs/moleculer-db) and many other modules... # Installation ``` $ npm i moleculer ``` or ``` $ yarn add moleculer ``` # Create your first microservice This example shows you how to create a small service with an `add` action which can add two numbers and how to call it. ```js const { ServiceBroker } = require("moleculer"); // Create a broker const broker = new ServiceBroker(); // Create a service broker.createService({ name: "math", actions: { add(ctx) { return Number(ctx.params.a) + Number(ctx.params.b); } } }); // Start broker broker.start() // Call service .then(() => broker.call("math.add", { a: 5, b: 3 })) .then(res => console.log("5 + 3 =", res)) .catch(err => console.error(`Error occurred! ${err.message}`)); ``` [Try it in your browser](https://codesandbox.io/s/ky5lj09jv?fontsize=14) # Create a Moleculer project Use the Moleculer CLI tool to create a new Moleculer based microservices project. 1. Create a new project (named `moleculer-demo`) ```bash $ npx moleculer-cli -c moleculer init project moleculer-demo ``` 2. Open the project folder ```bash $ cd moleculer-demo ``` 3. Start the project ```bash $ npm run dev ``` 4. Open the [http://localhost:3000/](http://localhost:3000/) link in your browser. It shows a welcome page that contains more information about your project & you can test the generated services. :tada: **Congratulations! Your first Moleculer-based microservices project is created. Read our [documentation](https://moleculer.services/docs) to learn more about Moleculer.** # Official modules We have many official modules for Moleculer. [Check our list!](https://moleculer.services/modules.html) # Supporting Moleculer is an open source project. It is free to use for your personal or commercial projects. However, developing it takes up all our free time to make it better and better on a daily basis. If you like Moleculer framework, **[please support it](https://moleculer.services/support.html)**. Thank you very much! # For enterprise Available as part of the Tidelift Subscription. The maintainers of moleculer and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-moleculer?utm_source=npm-moleculer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) # Documentation You can find here [the documentation](https://moleculer.services/docs). # Changelog See [CHANGELOG.md](CHANGELOG.md). # Security contact information To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. # Contributions We welcome you to join in the development of Moleculer. Please read our [contribution guide](http://moleculer.services/docs/contributing.html). [](https://github.com/moleculerjs/moleculer/graphs/contributors) ## Project activity # License Moleculer is available under the [MIT license](https://tldrlegal.com/license/mit-license). # Contact Copyright (c) 2016-2026 MoleculerJS [](https://github.com/moleculerjs) [](https://twitter.com/MoleculerJS) [patreon]: https://www.patreon.com/bePatron?u=6245171 --- ## File: docs/MIGRATION_GUIDE_0.13.md # Migration guide to v0.13.x This documentation leads you how you can migrate your project to be compatible with the Moleculer v0.13.x versions. > Please note! The previous version of `moleculer-web` doesn't work with Moleculer 0.13. You need to upgrade it to 0.8.x version too. ## 1. Always start the broker before call services > If you are using [Moleculer Runner](http://moleculer.services/docs/0.12/runner.html) with `moleculer.config.js`, skip this part. The ServiceBroker & Service lifecycle handler logic has been changed. **It works in the previous version** ```js const { ServiceBroker } = require("moleculer"); const broker = new ServiceBroker(); broker.loadService("./math.service.js"); broker.call("math.add", { a: 5, b: 3 }).then(res => console.log); // Prints: 8 ``` Since v0.13 it will throw a `ServiceNotFoundError` exception because the service is only loaded but not started yet. **Correct logic** ```js const { ServiceBroker } = require("moleculer"); const broker = new ServiceBroker(); broker.loadService("./math.service.js"); broker.start().then(() => { broker.call("math.add", { a: 5, b: 3 }).then(res => console.log); // Prints: 8 }); ``` It can cause problems in your tests as well. Make sure you use `broker.start()` and `broker.stop()` in all test cases. **Good test case** ```js describe("Test 'posts.find' action", () => { let broker = new ServiceBroker({ logger: false }); let actionHandler = jest.fn(ctx => ctx); broker.createService({ name: "posts", actions: { find: actionHandler } }); /* The important part! */ beforeAll(() => broker.start()); afterAll(() => broker.stop()); it("should call action handler", () => { return broker.call("posts.find", { id: 5 }).then(ctx => { expect(ctx.params).toEqual({ id: 5 }); expect(actionHandler).toHaveBeenCalledTimes(1); expect(actionHandler).toHaveBeenCalledWith(ctx); }); }); }); ``` ## 2. `console` is the new default logger No more need to set `logger: console` in broker options because ServiceBroker uses `console` as default logger. **Side effect:** broker instances in your tests will print log messages. To disable logging (default behavior in previous version) set `logger: false` in broker options. **Disable loggging** ```js const broker = new ServiceBroker({ logger: false }); ``` ## 3. Internal event sending logic is changed If you use `$` prefixed custom events in your project, be careful because now these events will be transferred to remote nodes too if you emit them with `broker.emit` or `broker.broadcast` methods. To previous behavior emit them with `broker.broadcastLocal` method. **By the way, we don't recommend to use `$` custom events because the prefix is reserved for core modules & features.** ## 4. Circuit Breaker logic & options have been changed **Old options** ```js const broker = new ServiceBroker({ circuitBreaker: { enabled: true, maxFailures: 5, halfOpenTime: 10 * 1000, failureOnTimeout: true, failureOnReject: true } }); ``` **New options** ```js const broker = new ServiceBroker({ nodeID: "node-1", circuitBreaker: { enabled: true, threshold: 0.5, minRequestCount: 20, windowTime: 60, // in seconds halfOpenTime: 5 * 1000, check: err => err && err.code >= 500 } }); ``` **Steps:** 1. Change `maxFailures` (count) to `threshold` (percent from 0.0 to 1.0) 2. Change `failureOnTimeout` & `failureOnReject` to a `check` function. > **Tips** > > All options can be overwritten in action: > ```js > module.export = { > name: "users", > actions: { > create: { > circuitBreaker: { > threshold: 0.3, > windowTime: 30 > }, > handler(ctx) {} > } > } > }; > ``` ## 6. Retry options has been changed Now it uses exponential backoff for retries. **Old options** ```js const broker = new ServiceBroker({ requestRetry: 5 }); ``` **New options** ```js const broker = new ServiceBroker({ nodeID: "node-1", retryPolicy: { enabled: true, retries: 5, delay: 100, maxDelay: 2000, factor: 2, check: err => err && !!err.retryable } }); ``` Overwrite the retries value in calling option The `retryCount` calling options has been renamed to `retries`. ```js broker.call("posts.find", {}, { retries: 3 }); ``` > **Tips** > > All options can be overwritten in action: > ```js > module.export = { > name: "users", > actions: { > find: { > retryPolicy: { > // All Retry policy options can be overwritten from broker options. > retries: 3, > delay: 500 > }, > handler(ctx) {} > }, > create: { > retryPolicy: { > // Disable retries for this action > enabled: false > }, > handler(ctx) {} > } > } > }; > ``` ## 7. Context tracking changes **Old options** ```js const broker = new ServiceBroker({ trackContext: true }); ``` **New options** ```js const broker = new ServiceBroker({ nodeID: "node-1", tracking: { enabled: true, shutdownTimeout: 5000 } }); ``` Disable tracking in calling option at calling ```js broker.call("posts.find", {}, { tracking: false }); ``` > The shutdown timeout can be overwritten by $shutdownTimeout property in service settings. ## 8. Internal statistics module has been removed If you need it, download from [here](https://gist.github.com/icebob/99dc388ee29ae165f879233c2a9faf63), load as a service and call the `stat.snapshot` to receive the collected statistics. ## 9. Renamed errors Some errors have been renamed in order to follow name conventions. - `ServiceNotAvailable` -> `ServiceNotAvailableError` - `RequestRejected` -> `RequestRejectedError` - `QueueIsFull` -> `QueueIsFullError` - `InvalidPacketData` -> `InvalidPacketDataError` If you check the `err.name` or `instanceof` in your code, you should check these parts and update to the new error names. ## 10. Context nodeID changes The `ctx.callerNodeID` has been removed. The `ctx.nodeID` always contains the target or caller nodeID. **Steps:** 1. Search `callerNodeID` in your project and change them to `ctx.nodeID`. ## 11. Enhanced ping method It returns `Promise` with results of ping responses. Moreover, the method is renamed to `broker.ping`. **Ping all known nodes** ```js broker.ping().then(res => broker.logger.info(res)); ``` **Output:** ```js { server: { nodeID: 'server', elapsedTime: 10, timeDiff: -2 } } ``` **Steps:** 1. If you uses `broker.sendPing` in your project, rename it to `broker.ping` and handle the returned `Promise`. ## 12. Cacher changes ### Cacher key generation logic has been changed The cacher key generation has been changed. If you uses Redis cacher, the old <=0.12 cacher won't find the new 0.13 cache entries. ### Cacher matcher has been changed The cacher matcher code is changed in `cacher.clean` method. The previous (wrong) matcher didn't handle dots (.) properly in patterns. E.g the `posts.*` pattern cleaned the `posts.find.something` keys too. Now it has been fixed, but it means that you should use `posts.**` pattern because the `params` and `meta` values can contain dots. ## 13. Moleculer errors signature has been changed Some Moleculer Error class constructor signature has been changed. **Steps:** 1. If you create Moleculer errors in your projects, please check the constructor signature of these errors. ## 13 + 1. Migrate your middleware to Middleware v2 (optional) > It's not a breaking change because old middleware works with Moleculer v0.13, but it's recommended to do. The new middleware is an `Object` with hooks instead of a simple `Function`. **Legacy old middleware** ```js const broker = new ServiceBroker({ middlewares: [ function(handler, action) { // Wrap the handler if neccessary } ] }); ``` **Migrated new middleware** ```js const broker = new ServiceBroker({ middlewares: [ { localAction: function(handler, action) { // Wrap the handler if neccessary } } ] }); ``` > The `broker.use` method to register middlewares has been deprecated. Please use `middlewares:[]` in broker options instead. **List of all available hooks in new middlewares:** ```js const MyCustomMiddleware = { // Wrap local action handlers (legacy middleware handler) localAction(next, action) { }, // Wrap remote action handlers remoteAction(next, action) { }, // Wrap local event handlers localEvent(next, event) { } // Wrap broker.createService method createService(next) { } // Wrap broker.destroyService method destroyService(next) { } // Wrap broker.call method call(next) { } // Wrap broker.mcall method mcall(next) { } // Wrap broker.emit method emit(next) { }, // Wrap broker.broadcast method broadcast(next) { }, // Wrap broker.broadcastLocal method broadcastLocal(next) { }, // After a new local service created (sync) serviceCreated(service) { }, // Before a local service started (async) serviceStarting(service) { }, // After a local service started (async) serviceStarted(service) { }, // Before a local service stopping (async) serviceStopping(service) { }, // After a local service stopped (async) serviceStopped(service) { }, // After broker is created (async) created(broker) { }, // Before broker starting (async) starting(broker) { }, // After broker started (async) started(broker) { }, // Before broker stopping (async) stopping(broker) { }, // After broker stopped (async) stopped(broker) { } } ``` ----------- **:tada: Well, you are done! :clap:** Happy coding in your brand new Moleculer project. If you need help, join to [Gitter chat](https://gitter.im/moleculerjs/moleculer) and don't hesitate to ask Moleculer community. --- ## File: docs/MIGRATION_GUIDE_0.14.md # Migration guide to v0.14.x This documentation leads you how you can migrate your project to be compatible with the Moleculer v0.14.x versions. >Please note, the communication protocol has been changed. It means the new Moleculer 0.14 nodes can't communicate with old <= 0.13 nodes. ## 1. Check your validation setting in broker options. The `validation: true` broker options was removed to follow other module configuration. Use `validator` option, instead. ### Disable validator **Old options** ```js // moleculer.config.js module.exports = { validation: false }; ``` **New options** ```js // moleculer.config.js module.exports = { validator: false }; ``` ### Use custom validator **Old options** ```js // moleculer.config.js module.exports = { validation: true validator: new MyCustomValidator() }; ``` **New options** ```js // moleculer.config.js module.exports = { validator: new MyCustomValidator() }; ``` ## 2. Don't use `broker.use`, use `middleware` broker option instead The `broker.use` has been deprecated in version 0.13 and now it is removed. Use `middleware: []` broker options to define middlewares. **Legacy middleware adding** ```js const broker = new ServiceBroker({}); broker.use(myMiddleware); ``` **New middleware adding** ```js // moleculer.config.js module.exports = { middlewares: [ myMiddleware1, myMiddleware2, ] }; ``` ## 3. Don't use middleware shorthand functions In previous versions you could define middleware which wraps the `localAction` hook with a simple `Function`. In version 0.14 this legacy shorthand is dropped. When you define a middleware as a `Function`, the middleware handler will call it as an initialization and pass the ServiceBroker instance as a parameter. **Legacy shorthand middleware definition as a `Function`** ```js const MyMiddleware = function(next, action) { return ctx => next(ctx); }; ``` **Accepted middleware definition** ```js const MyMiddleware = { localAction: function(next, action) { return ctx => { myLogger.info(`${action.name} has been called`); return next(ctx); } } }; ``` **Accepted middleware definition as a `Function`** In this case, you have a pointer to the `broker`. ```js const MyMiddleware = function(broker) { // Create a custom named logger const myLogger = broker.getLogger("MY-LOGGER"); return { localAction: function(next, action) { return ctx => { myLogger.info(`${action.name} has been called`); return next(ctx); } } } }; ``` ## 4. Use the new context-based event handler signature Moleculer detects the signature of your event handler. If it finds that the signature is `"user.created(ctx) { ... }`, it will call it with Event Context. If not, it will call with old arguments & the 4th argument will be the Event Context, like `"user.created"(payload, sender, eventName, ctx) {...}` **Legacy event handler signature** ```js module.exports = { name: "accounts", events: { "user.created"(payload, sender, eventName) { ... } } }; ``` **Legacy event handler signature with context** ```js module.exports = { name: "accounts", events: { "user.created"(payload, sender, eventName, ctx) { ... } } }; ``` **New context-based event handler signature** ```js module.exports = { name: "accounts", events: { "user.created"(ctx) { // legacy `payload` is in `ctx.params` // legacy `sender` is in `ctx.nodeID` // legacy `eventName` is in `ctx.eventName` } } }; ``` ### The `localEvent` handler signature in middlewares Please check the `localEvent` handler signature in your custom middlewares, as well. It should follow the new context-based signature. **New context-based signature in middleware `localEvent` hook** ```js // my-middleware.js module.exports = { // Wrap local event handlers localEvent(next, event) { return (ctx) => { return next(ctx); }; }, }; ``` ## 5. The `node.health` response changed The `$node.health` action's response has been changed. The `transit` property is removed. To get transit metrics, use the new `$node.metrics` internal action. ## 6. Use the new metrics & tracing features **Old broker options** ```js // moleculer.config.js module.exports = { metrics: true, metricsRate: 1.0 }; ``` **New broker options** ```js // moleculer.config.js module.exports = { metrics: { enabled: true, }, tracing: { enabled: true, exporters: [ { type: "Zipkin", options: { baseURL: "http://zipkin-server:9411", } }, { type: "Jaeger", options: { host: "jaeger-server", port: 6832 } } ], sampling: { rate: 1.0, // 0.0 - Never, 1.0 > x > 0.0 - Fix, 1.0 - Always tracesPerSecond: null, // 1: 1 trace / sec, 5: 5 traces / sec, 0.1: 1 trace / 10 secs minPriority: null }, actions: true, events: false, errorFields: ["name", "message", "code", "type", "data"], stackTrace: false, defaultTags: null, } }; ``` **Old way to add params & meta fields to tracing spans** ```js // posts.service.js module.exports = { name: "posts", actions: { get: { metrics: { params: ["id"], meta: ["loggedIn.username"], }, async handler(ctx) { // ... } } } }); ``` **New way to add params, meta or response fields to tracing spans** ```js // posts.service.js module.exports = { name: "posts", actions: { get: { tracing: { tags: { params: ["id"], meta: ["loggedIn.username"], response: ["id", "title"] // add data to tags from the action response. }, async handler(ctx) { // ... } } } }); ``` ## 6. Use a new built-in logger instead of a custom logger. The whole logging function has been rewritten in this version. It means, it has a lot of new features, but the configuration of loggers has contains breaking changes. **Old way to use an external logger** ```js // moleculer.config.js module.exports = { logger: bindings => pino.child(bindings), }; ``` ```js // moleculer.config.js module.exports = { logger: { type: "Pino", options: { // Logging level level: "info", pino: { // More info: http://getpino.io/#/docs/api?id=options-object options: null, // More info: http://getpino.io/#/docs/api?id=destination-sonicboom-writablestream-string destination: "/logs/moleculer.log", } } } }; ``` If you have your custom logger you should wrap it into a `Logger` class and implement the `getLogHandler` method. **Using a custom logger** ```js // moleculer.config.js const BaseLogger = require("moleculer").Loggers.Base; class MyLogger extends BaseLogger { getLogHandler(bindings) { return (type, args) => console[type](`[MYLOG-${bindings.mod}]`, ...args); } } module.exports = { logger: new MyLogger() }; ``` >[Read more about the new logging feature and all supported loggers.](https://moleculer.services/docs/0.14/logging.html) ## 7. Bluebird is dropped The Bluebird Promise library has been dropped from the project because as of Node 10, the native `Promise` implementation is [faster (2x)](https://github.com/icebob/js-perf-benchmark/blob/95803284dcb46c403eb71f2f114b76bf669189ce/suites/promise.js#L123-L133) than Bluebird. If you want to use Bluebird instead of native Promise, just set the `Promise` broker options. ```js const BluebirdPromise = require("bluebird"); // moleculer.config.js module.exports = { Promise: BluebirdPromise }; ``` >Please note, the given Promise library will be polyfilled with `delay`, `method`, `timeout` and `mapSeries` methods (which are used inside Moleculer modules). If you are using Typescript you will need to augment the moleculer declarations to override the returned promise type from Bluebird. You will need to have a .d.ts file with the following code when you compile: ```ts import Bluebird from "bluebird"; declare module "moleculer" { type Promise = Bluebird; } ``` Additionally, if you were using `PromiseLike` as a type for anything being returned by moleculer, this will need to be converted to `Promise`, regardless of whether you are using native promises or third-party promises. ## 8. Typescript definitions are more strict The 0.13 release was very loose on the typings for `params` and `meta` for the `Context` class and the `call`, `emit`, and `broadcast` methods from the `Context` and `ServiceBroker` classes. If Generics were not provided to these types, the default behavior would return `any`: ```ts type GenericObject = { [name: string]: any }; ... class Context { ... params: P; meta: M; ... call(actionName: string, params?: P, opts?: GenericObject): PromiseLike; emit(eventName: string, data: D, groups: Array): void; emit(eventName: string, data: D, groups: string): void; emit(eventName: string, data: D): void; broadcast(eventName: string, data: D, groups: Array): void; broadcast(eventName: string, data: D, groups: string): void; broadcast(eventName: string, data: D): void; ``` Without providing generic overrides, these types afforded absolutely no type safety because your incoming `params` and `meta` in `Context` were all typed as `any`, the return value from `call` would be typed as `any`, the parameters provided to `call` would allow for any object, and the payload provided to `emit` and `broadcast` could be `any`. In 0.14, the default signature has been tightened up as the following: ```ts class Context { ... params: P; meta: M; ... call(actionName: string): PromiseLike; call(actionName: string, params: P, opts?: GenericObject): PromiseLike; emit(eventName: string, data: D, opts: GenericObject): PromiseLike; emit(eventName: string, data: D, groups: Array): PromiseLike; emit(eventName: string, data: D, groups: string): PromiseLike; emit(eventName: string, data: D): PromiseLike; emit(eventName: string): PromiseLike; broadcast(eventName: string, data: D, opts: GenericObject): PromiseLike; broadcast(eventName: string, data: D, groups: Array): PromiseLike; broadcast(eventName: string, data: D, groups: string): PromiseLike; broadcast(eventName: string, data: D): PromiseLike; broadcast(eventName: string): PromiseLike; ``` Effectively, if generics are not provided then `params` will be typed as `unknown` and `meta` will be typed as an empty object. The `return` value of `call` will be `unknown`. You could pass any payload to `emit` and `broadcast` without any validation. Since moleculer is calling services and passing parameters over the wire, it cannot discern what the type of params and called action return values are without guidance. The generics provide that guidance and allow for type safety in your application. If you've already been providing generics to these types then congratulations(!), there is nothing you need to do. If you have not been providing generics to these types then you are likely to find that you will be getting type errors because values that were previously typed as `any` will now be `unknown`. You will need to update your types to provide types for these generics to avoid the type errors. There are a couple of approaches to remedying these type issues: 1. (**recommended**) Provided proper types for these generics in `Context`, `call`, `emit`, and `broadcast`. You will now have type safety for your `ctx.params`, `ctx.meta`, return values from `call`, `params` passed to `call`, and payloads passed to `emit` and `broadcast`. 2. (not recommended) Augment the moleculer module with your own local TS definitions that revert these types to their previous behavior. This will make your code work exactly as it was previously, with no type of safety afforded. 3. (not recommended) Replace all uses of the `Context` type in your application with `Context`, `call` with `call`, `emit` with `emit` and `broadcast` with `broadcast`. As with #2, you will still not have type safety, but it may represent a quick and dirty approach. **NOTE:** The examples above show the changes to the `Context` class but similar changes were made to the `ServiceBroker` class as well. Any changes that you need to make for `Context` will be needed for `ServiceBroker` as well. **:tada: Well, you are done! :clap:** Happy coding in your up-to-date Moleculer project. If you need help, join [Discord chat](https://discord.gg/j5cJYdu) and don't hesitate to ask Moleculer community. --- ## File: docs/profiling.md # Profiling in NodeJS 1. Run app in profiler mode ``` $ node --prof main.js ``` 2. Convert isolate file to text ``` $ node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt ``` [More info](https://nodejs.org/en/docs/guides/simple-profiling/) ## Print optimizing ``` $ node --trace-opt index.js > trace.txt ``` With de-optimizing ``` $ node --trace-opt --trace-deopt index.js > trace.txt ``` More info: https://community.risingstack.com/how-to-find-node-js-performance-optimization-killers/ ## Inspecting & Profiling in Chrome `node --inspect --expose-gc benchmark/perf-runner.js` ## IR Hydra http://mrale.ph/irhydra/2/ ``` $ node --trace-hydrogen --trace-phase=Z --trace-deopt --code-comments --hydrogen-track-positions --redirect-code-traces --redirect-code-traces-to=code.asm index.js ``` ## JSON parse/stringify https://github.com/douglascrockford/JSON-js ## Flame graph http://www.brendangregg.com/blog/2014-09-17/node-flame-graphs-on-linux.html https://www.slideshare.net/brendangregg/blazing-performance-with-flame-graphs For Windows: https://github.com/google/UIforETW/releases ### 0x https://github.com/davidmarkclements/0x Installation: ``` npm install 0x ``` Usage: ``` 0x -o index.js ``` > for pwsh users, switch to CMD at first or run with `npx` > ``` npx 0x -o index.js ``` ## Others http://mrale.ph/blog/2011/12/18/v8-optimization-checklist.html http://stackoverflow.com/a/31549736/129346 https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#52-the-object-being-iterated-is-not-a-simple-enumerable https://jsperf.com/let-compound-assignment https://gist.github.com/trevnorris/f0907b010c9d5e24ea97 ## Memory leak https://www.youtube.com/watch?v=taADm6ndvVo&list=PLz6xH_GrBpquZgdVzEX4Bix0oxHQlZfwm&index=8 --- ## File: docs/PROTOCOL.md title: Protocol --- The protocol documentation moved to a separated repo: https://github.com/moleculer-framework/protocol --- ## File: src/tracing/exporters/README.md # Moleculer Trace Exporters ## Running Jaeger ```bash docker run -d --name jaeger -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14250:14250 -p 14268:14268 -p 14269:14269 jaegertracing/all-in-one:latest ``` **UI:** http://:16686/ ## Running Zipkin ```bash docker run -d -p 9411:9411 --name=zipkin openzipkin/zipkin ``` ## Running DataDog Agent ```bash docker run -d --name dd-agent --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock:ro -v /proc/:/host/proc/:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e DD_API_KEY=123456 -e DD_APM_ENABLED=true -e DD_APM_NON_LOCAL_TRAFFIC=true -p 8126:8126 datadog/agent:latest ```