{"id":17465519,"url":"https://github.com/nidhhoggr/pmon3","last_synced_at":"2026-01-12T01:54:50.355Z","repository":{"id":214718132,"uuid":"737191186","full_name":"nidhhoggr/pmon3","owner":"nidhhoggr","description":"Golang Production Process Manager","archived":false,"fork":false,"pushed_at":"2025-03-01T22:27:39.000Z","size":14835,"stargazers_count":15,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-11-22T19:17:29.437Z","etag":null,"topics":["golang","linux","macosx","pm2","pmon2","process-manager"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nidhhoggr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2023-12-30T05:57:51.000Z","updated_at":"2025-08-29T08:03:43.000Z","dependencies_parsed_at":"2024-01-02T03:31:05.808Z","dependency_job_id":"5dd22590-f73d-45ff-8722-217a4a31d54d","html_url":"https://github.com/nidhhoggr/pmon3","commit_stats":null,"previous_names":["joe-at-startupmedia/pmon2","joe-at-startupmedia/pmon3","nidhhoggr/pmon3"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/nidhhoggr/pmon3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidhhoggr%2Fpmon3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidhhoggr%2Fpmon3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidhhoggr%2Fpmon3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidhhoggr%2Fpmon3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nidhhoggr","download_url":"https://codeload.github.com/nidhhoggr/pmon3/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidhhoggr%2Fpmon3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28331297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"ssl_error","status_checked_at":"2026-01-12T00:36:15.229Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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"}},"keywords":["golang","linux","macosx","pm2","pmon2","process-manager"],"created_at":"2024-10-18T12:05:57.760Z","updated_at":"2026-01-12T01:54:50.338Z","avatar_url":"https://github.com/nidhhoggr.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pmon3\n[![CI](https://github.com/nidhhoggr/pmon3/actions/workflows/ci.yml/badge.svg)](https://github.com/nidhhoggr/pmon3/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/nidhhoggr/pmon3/graph/badge.svg?token=RAILGSJ6XQ)](https://codecov.io/gh/nidhhoggr/pmon3)\n[![Release](https://img.shields.io/github/v/release/nidhhoggr/pmon3)](https://github.com/nidhhoggr/pmon3/releases/latest)\n\n\n`pmon3` is a process manager (currently supports Linux and MacOSX) which allows you to keep processes alive forever. Processes can be declared directly via the [CLI](#section_commands) or in a [configuration file](#section_processconfig). `pmon3` allows you to get started quickly while providing configuration granularity at both the [system](#section_config) and [process](#section_processconfig) levels.\n\n\u003cimg width=\"537\" alt=\"pmon3_ls\" src=\"https://github.com/nidhhoggr/pmon3/assets/13522698/5d79ad53-664d-4ee7-bfac-f3fc94c2b316\"\u003e\n\n* [Introduction](#section_intro)\n* [Installation](#section_install)\n* [CLI Commands](#section_commands)\n* [System Configuration](#section_config)\n* [Process Configuration](#section_processconfig)\n* [Process Dependencies](#section_dependencies)\n* [Groups](#section_groups)\n* [Event Handling](#section_events)\n* [Flap Detection/Prevention](#section_flapping)\n* [Debugging](#section_debugging)\n* [Performance](#section_performance)\n* [Problems](#section_problems)\n\n\u003ca name=\"section_intro\"\u003e\u003c/a\u003e\n## Introduction\n\nGolang currently has no officially supported process management tools. For managing processes, some use built-in commands such as `nohup [process] \u0026`, or the process management tools provided by the operating system such as systemd. Alternatively, third-party process management tools such as Supervisor (python) or PM2 (node.js) can also be utilized.\n\nUnlike PM2, `pmon3` is managed directly by the OS process manager, so if the `pmon3` CLI abnormally terminates, it will not affect the `pmond` daemon process. This is currently achieved by separating the `pmond` daemon process from the `pmon3` CLI.\n\nBy default, if a process abnormally terminates, `pmond` will try to restart the process. If you don't want a process to restart automatically, you can provide the `--no-autorestart` parameter flag from the CLI.\n\n\u003ca name=\"section_install\"\u003e\u003c/a\u003e\n## Installation\n\n[Releases](https://github.com/nidhhoggr/pmon3/releases) \n\n### Using Go\n\n```bash\n  git clone https://github.com/nidhhoggr/pmon3/ \u0026\u0026 cd pmon3 \n  go mod tidy\n  go build -o bin/pmon3 cmd/pmon3/pmon3.go\n  go build -o bin/pmond cmd/pmond/pmond.go\n  cp -R bin/pmon* /usr/local/bin/\n  #create the configuration directory\n  mkdir -p /etc/pmon3/config/\n  cp config.yml /etc/pmon3/config/\n  #start the daemon\n  sudo /usr/local/bin/pmond \u0026\n```\n\n### Makefile\nThe systemd installation process entails the following steps:\n1. create the configuration directory\n1. create the log rotation file\n1. create the bash completion profile (requires the bash-completion package)\n1. enable and start the `pmond` system service\n\n```bash\n#build the project\nmake build\n#install on systemd-based system\nmake systemd_install\n```\n\n\u003ca name=\"release_installer\"\u003e\u003c/a\u003e\n### Release Installer\n\n```bash\nwget -O - https://raw.githubusercontent.com/nidhhoggr/pmon3/master/release-installer.bash | bash\n```\n\n:exclamation: After installing `pmon3` for the first time, both installation methods provided above should automatically enable and start the service. if the `pmond` service does not start automatically, you need to manually start the service.\n\n```bash\nsudo systemctl start pmond\n\n# Others\nsudo /usr/local/bin/pmond \u0026\n```\n\n\u003ca name=\"section_commands\"\u003e\u003c/a\u003e\n## CLI Commands\n\n### Help\n\n```\nUsage:\n  pmon3 [command]\n\nAvailable Commands:\n  completion  Generate completion script\n  del         Delete process by id or name\n  desc        Show process information by id or name\n  dgraph      Show the process queue order\n  drop        Delete all processes\n  exec        Spawn a new process\n  export      Export Process Configuration\n  group       Group level commands\n  help        Help about any command\n  init        Initialize all stopped processes\n  kill        Terminate all processes\n  log         Display process logs by id or name\n  logf        Tail process logs by id or name\n  ls          List all processes\n  reset       Reset the restart counter(s)\n  restart     (Re)start a process by id or name\n  stop        Stop a process by id or name\n  topn        Shows processes with unix top cmd\n  version\n\nFlags:\n  -h, --help   help for pmon3\n\nUse \"pmon3 [command] --help\" for more information about a command.\n```\n\n\u003ca name=\"pmon3_exec\"\u003e\u003c/a\u003e\n### Creating a process [run/exec]\n\n```bash\npmon3 exec [process_binary] [flags]\n```\n\n\u003ca name=\"exec_flags\"\u003e\u003c/a\u003e\nThe starting process accepts several parameters. The parameter descriptions are as follows:\n\n```\n// The process name. It will use the file name of the binary as the default name if not provided \n--name\n\n// Where to store logs. It will override the confuration files `logs_dir` property\n--log-dir\n\n// The absolute path of a custom log file\n--log  -l\n\n// Provide parameters to be passed to the binary, multiple parameters are separated by spaces\n--args  -a \"-arg1=val1 -arg2=val2\"\n\n// Provide environment variables (appended to those already existing on the system `os.Environ()`)\n--env-vars \"ENV_VAR_1=env_var_1_value ENV_VAR_2=env_var_2_value\"\n\n// managing user\n--user -u\n\n// Do not restart automatically. It will automatically restart by default.\n--no-autorestart  -n\n\n// Provide a list of process names that this process will depend on\n--dependencies parent-process-name [--dependencies parent-process-name2]...\n\n//provide a list of group names this process is associated to\n--groups group-name-one [--groups group-name-2]\n```\n\n#### Example：\n\n```bash\npmon3 exec ./bin/gin --args \"-prjHome=`pwd`\" --user joe\n```\n\n:exclamation: Parameter arguments need to use the absolute path.\n\n### View List  [list/ls]\n\n```bash\npmon3 ls\n```\n\n### (re)start the process [restart/start]\n\n```bash\npmon3 restart [id or name]\n```\n\n\u003ca name=\"pmon3_stop\"\u003e\u003c/a\u003e\n### Stop the process  [stop]\n\n```bash\npmon3 stop [id or name]\n```\n\n### Process logging\n\n```bash\n# view logs of the process specified\npmon3 log [id or name]\n\n# view logs of the process specified including those previously rotated/archived\npmon3 log -a [id or name]\n\n# Similar to using `tail -f xxx.log`\npmon3 logf [id or name]\n```\n\n### Delete the process  [del/delete]\n\n```bash\npmon3 del [id or name]\n```\n\n### View details [show/desc]\n\n```bash\npmon3 show [id or name]\n```\n\n\u003cimg width=\"475\" alt=\"pmon3_show\" src=\"https://github.com/nidhhoggr/pmon3/assets/13522698/6b564a1c-0e26-468c-bd01-6dabce0c7620\"\u003e\n\n\u003ca name=\"pmon3_kill\"\u003e\u003c/a\u003e\n### Terminate all running process [kill]\n```bash\npmon3 kill [--force]\n```\n\n\u003ca name=\"pmon3_init\"\u003e\u003c/a\u003e\n### (re)start all stopped process [init]\n```bash\n#(re)start processes specified in the Process Config only\npmon3 init --process-config-only\n\n#(re)start processes specified in the Process Config and those which already exist in the database\npmon3 init\n```\n\n\u003ca name=\"pmon3_drop\"\u003e\u003c/a\u003e\n### Terminate and delete all processes [drop]\n```bash\npmon3 drop [--force]\n```\n\n\u003ca name=\"pmon3_dgraph\"\u003e\u003c/a\u003e\n### Display the dependency graph [dgraph/order]\n\nThis command is useful to debug dependency resolution without (re)starting processes\n\n```bash\n#processes specified in the Process Config only\npmon3 dgraph --process-config-only\n\n#processes specified in the Process Config and the database\npmon3 dgraph\n```\n\n\u003ca name=\"pmon3_reset\"\u003e\u003c/a\u003e\n### Reset the restart counter(s) [reset]\n\nThis command will reset the restart counter back to 0. This is useful to establish a clean slate without having to restart the pmond process.\n\n```bash\n#reset the restart counter on all processes\npmon3 reset\n\n#reset the restart counter on a specific process\npmon3 reset [process_id_or_name]\n```\n\n\u003ca name=\"pmon3_export\"\u003e\u003c/a\u003e\n### Export Process Configuration [export]\n\nThis command is useful when you want to generate [Process Configuration](#section_appconfig) to use for pmond initialization from the specified `process_config_file`.\n\n```bash\npmon3 export\n\n#specify json as a format (default)\npmon3 export json\n\n#specify toml as a format\npmon3 export toml\n\n#specify yaml as a format\npmon3 export yaml\n\n#order by name ascending instead of id\npmon3 export yaml -o name\n```\n\n### Top Native [topn]\n\nThis will output the resource utilization of all processes using the native `top` command that is pre-installed on most unix-based operating systems. It will only show those processes managed by (and including) the `pmond` process.\n\n```bash\npmon3 topn\n```\n\u003cimg width=\"559\" alt=\"pmon3_topn\" src=\"https://github.com/nidhhoggr/pmon3/assets/13522698/a77cce0f-55b0-479f-8489-d6aaf9fcdd6b\"\u003e\n\n\u003ca name=\"section_config\"\u003e\u003c/a\u003e\n## System Configuration\nThe default path of the configuration file is `/etc/pmon3/config/config.yml`. This value can be overridden with the `PMON3_CONF` environment variable. \nThe following configuration options are available:\n```yaml\n# log levels: debug/info/warn/error\nlog_level: info\n\n# kill processes on termination\nhandle_interrupts: true\n\n# whether to reload from the configuration before executing a command\ndisable_reloads: false\n\n# poll processes every [n] milliseconds\nprocess_monitor_interval: 500\n\n# wait [n] seconds before monitoring process statuses\ninitialization_period: 30\n\n# a configuration file to specify a list of processes to start on the first initialization (json, yaml or toml)\nprocess_config_file: /etc/pmon3/config/process.config.json\n\nwait:\n  # wait [n] milliseconds before outputting list after running init/stop/restart/kill/drop/exec\n  cmd_exec_response: 1500\n  # wait [n] milliseconds after connecting to IPC client before issuing commands\n  ipc_connection: 0\n  # wait [n] milliseconds after enqueueing a dependent process\n  dependent_process_enqueued: 1000\n\n#permission settings applied to files and directories of data/logs/message_queue\npermissions:\n  # an OS user to access files in data/logs/message_queue directory\n  user:\n  # an OS group to access files in data/logs/message_queue directory (must also provide a user)\n  group:\n  # the mode to apply to the data/logs/message_queue directory\n  directory_mode: 0770\n  # the mode to apply to files within the data/logs/message_queue directory\n  file_mode: 0660\n\n#settings specific to the logs directory (inherits from permissions by default)\nlogs:\n  # directory where the logs are stored\n  directory: /var/log/pmond\n  # an OS user to access files in logs directory\n  user:\n  # an OS group to access files in logs directory (must also provide a user)\n  group:\n  # the mode to apply to the logs directory\n  directory_mode: 0775\n  # the mode to apply to files within the logs directory\n  file_mode:\n\n#settings specific to the data directory (inherits from permissions by default)\ndata:\n  # directory where the database is stored\n  directory: /etc/pmon3/data\n  # an OS user to access files in data directory\n  user:\n  # an OS group to access files in data directory (must also provide a user)\n  group:\n  # the mode to apply to the data directory\n  directory_mode:\n  # the mode to apply to files within the data directory\n  file_mode:\n\n#settings specific to the message_queue directory (inherits from permissions by default)\nmessage_queue:\n  # directory where the messages are stored\n  directory:\n    # custom shared memory directory\n    shmem: /dev/shm/\n    # custom posix_mq directory\n    posix_mq: /dev/mqueue/\n  # a string to append to the name of the queue\n  name_suffix:\n  # an OS user to access files in message_queue directory\n  user:\n  # an OS group to access files in message_queue directory (must also provide a user)\n  group:\n  # the mode to apply to the message_queue directory\n  directory_mode: 0775\n  # the mode to apply to files within the message_queue directory\n  file_mode: 0666\n\nevent_handling:\n  # a script to execute when a process is restarted which accepts the process details json as the first argument\n  process_restart:\n  # a script to execute when a process fails (--no-autorestart) which accepts the process details json as the first argument\n  process_failure:\n  # a script to execute when a process backs off when flap detection is enabled\n  process_backoff:\n\nflap_detection:\n  # enable flap detection\n  is_enabled: false\n  # the amount of times a process can restart (within the countdown threshold) until backoff evaluation begins\n  threshold_restarted: 5\n  # the amount of process monitor intervals during a processes backoff period until process evaluation proceeds as normal\n  threshold_countdown: 120\n  # the amount of process monitor intervals during a processes backoff period until the processes restart counter is decremented. disabled with 0 value.\n  threshold_decrement: 60\n```\n\nRestarting pmond is usually unnecessary: All configuration changes should take effect when the next command is issued.\n\n\u003ca name=\"section_config_envvars\"\u003e\u003c/a\u003e\n### Environment Variables\n\nThe configuration values can be overridden using environment variables:\n\n* `CONFIGOR_LOGLEVEL`\n* `CONFIGOR_HANDLEINTERRUPTS`\n* `CONFIGOR_PROCESSMONITORINTERVAL`\n* `CONFIGOR_INITIALIZATIONPERIOD`\n* `CONFIGOR_PROCESSCONFIGFILE`\n* `CONFIGOR_WAIT_CMDEXECRESPONSE`\n* `CONFIGOR_WAIT_IPCCONNECTION`\n* `CONFIGOR_WAIT_DEPENDENTPROCESSENQUEUED`\n* `CONFIGOR_PERMISSIONS_USER`\n* `CONFIGOR_PERMISSIONS_GROUP`\n* `CONFIGOR_PERMISSIONS_DIRECTORYMODE`\n* `CONFIGOR_PERMISSIONS_FILEMODE`\n* `CONFIGOR_LOGS_DIRECTORY`\n* `CONFIGOR_LOGS_USER`\n* `CONFIGOR_LOGS_GROUP`\n* `CONFIGOR_LOGS_DIRECTORYMODE`\n* `CONFIGOR_LOGS_FILEMODE`\n* `CONFIGOR_DATA_DIRECTORY`\n* `CONFIGOR_DATA_USER`\n* `CONFIGOR_DATA_GROUP`\n* `CONFIGOR_DATA_DIRECTORYMODE`\n* `CONFIGOR_DATA_FILEMODE`\n* `CONFIGOR_MESSAGEQUEUE_DIRECTORY`\n* `CONFIGOR_MESSAGEQUEUE_DIRECTORY_SHMEM`\n* `CONFIGOR_MESSAGEQUEUE_DIRECTORY_POSIXMQ`\n* `CONFIGOR_MESSAGEQUEUE_NAMESUFFIX`\n* `CONFIGOR_MESSAGEQUEUE_USER`\n* `CONFIGOR_MESSAGEQUEUE_GROUP`\n* `CONFIGOR_MESSAGEQUEUE_DIRECTORYMODE`\n* `CONFIGOR_MESSAGEQUEUE_FILEMODE`\n* `CONFIGOR_EVENTHANDLER_PROCESSRESTART`\n* `CONFIGOR_EVENTHANDLER_PROCESSFAILURE`\n* `CONFIGOR_FLAPDETECTION_ISENABLED`\n* `CONFIGOR_FLAPDETECTION_THRESHOLDRESTARTED`\n* `CONFIGOR_FLAPDETECTION_THRESHOLDCOUNTDOWN`\n* `CONFIGOR_FLAPDETECTION_THRESHOLDDECREMENT`\n\n\u003ca name=\"section_processconfig\"\u003e\u003c/a\u003e\n## Process Configuration\n\nBy default, when `pmond` is restarted from a previously stopped state, it will load all processes in the database that were: \n* previously running\n* have been marked as stopped as a result of pmond closing \n* have `--no-autorestart` set to false (default value)\n\n```yaml\n# a configuration file to specify a list of processes to start on the first initialization (json, yaml or toml)\nprocess_config_file: /etc/pmon3/config/process.config.json\n```\n\n### Supported Formats\n\n#### /etc/pmon3/config/process.config.json\n```json\n{\n  \"processes\": [\n    {\n      \"file\": \"/usr/local/bin/happac\",\n      \"name\": \"happac1\",\n      \"args\": \"-h startup-patroni-1.node.consul -p 5555 -r 5000\",\n      \"user\": \"vagrant\",\n      \"log_dir\": \"/var/log/custom/\",\n      \"dependencies\": [\"happac2\"],\n      \"groups\": [\"happac\"]\n    },\n    {\n      \"file\": \"/usr/local/bin/happab\",\n      \"name\": \"happac2\",\n      \"log\": \"/var/log/happac2.log\",\n      \"args\": \"-h startup-patroni-1.node.consul -p 5556 -r 5001\",\n      \"user\": \"vagrant\",\n      \"no_auto_restart\": true,\n      \"groups\": [\"happac\"]\n    },\n    {\n      \"file\": \"/usr/local/bin/node\",\n      \"name\": \"metabase-api\",\n      \"args\": \"/var/www/vhosts/metabase-api/index.js\",\n      \"env_vars\": \"NODE_ENV=prod\",\n      \"user\": \"dw_user\"\n    }\n  ]\n}\n```\n\n#### /etc/pmon3/config/process.config.yaml\n```yaml\nprocesses:\n  - file: \"/usr/local/bin/happac\"\n    name: happac1\n    args: \"-h startup-patroni-1.node.consul -p 5555 -r 5000\"\n    user: vagrant\n    log_dir: \"/var/log/custom/\"\n    dependencies:\n    - happac2\n    groups:\n    - happac\n  - file: \"/usr/local/bin/happab\"\n    name: happac2\n    log: \"/var/log/happac2.log\"\n    args: \"-h startup-patroni-1.node.consul -p 5556 -r 5001\"\n    user: vagrant\n    no_auto_restart: true\n    groups:\n    - happac\n  - file: \"/usr/local/bin/node\"\n    name: metabase-api\n    args: \"/var/www/vhosts/metabase-api/index.js\"\n    env_vars: NODE_ENV=prod\n    user: dw_user\n```\n\n#### /etc/pmon3/config/process.config.toml\nUnlike json and yaml, all fields are camel-cased:\n```toml\n[[Processes]]\n  File = \"/usr/local/bin/happac\"\n  Name = \"happac1\"\n  Args = \"-h startup-patroni-1.node.consul -p 5555 -r 5000\"\n  User = \"vagrant\"\n  LogDir = \"/var/log/custom/\"\n  Dependencies = [ \"happac2\" ]\n  Groups = [ \"happac\" ]\n\n[[Processes]]\n  File = \"/usr/local/bin/happab\"\n  Name = \"happac2\"\n  Log = \"/var/log/happac2.log\"\n  Args = \"-h startup-patroni-1.node.consul -p 5556 -r 5001\"\n  User = \"vagrant\"\n  NoAutoRestart = true\n  Groups = [ \"happac\" ]\n\n[[Processes]]\n  File = \"/usr/local/bin/node\"\n  Name = \"metabase-api\"\n  Args = \"/var/www/vhosts/metabase-api/index.js\"\n  EnvVars = \"NODE_ENV=prod\"\n  User = \"dw_user\"\n```\n\n### Generation Utility\n\nInstead of configuring this file from scratch you can use the [export](#pmon3_export) command to output the configuration from the current process list. This allows the administrator to build a process list using imperative commands followed by exporting the results to a configuration file.\n\n### Flags\n\nAll possible `flags` values matching those specified in the [exec](#exec_flags) command:\n\n* file\n* user\n* log\n* log_dir\n* no_auto_restart\n* args\n* env_vars\n* name\n* dependencies\n* groups\n\n\u003ca name=\"section_dependencies\"\u003e\u003c/a\u003e\n## Dependencies\n\nDependencies (provided as an array) determine the order in which the processes are started. They are sorted using a directed acyclic graph meaning that there cannot be cyclical dependencies between processes. Dependency resolution can be debugged using the [dgraph](#pmon3_dgraph) command. Parent processes can wait `[n]` amount of seconds between spawning dependent processes by utilizing the `dependent_process_enqueued` configuration variable (currently defaults to `2` seconds).\n\n\u003ca name=\"section_groups\"\u003e\u003c/a\u003e\n## Groups\n\nGroups are useful when dealing with a large amount of related processes. Like processes, they are stored in the database and provide many-to-many cardinality. This allows the ability to associate multiple groups to one or more processes and vice versa. Groups can be managed via [Process Configuration](#section_processconfig) and through the [CLI](#exec_flags).\n\n### Commands\n```\nGroup level commands\n\nUsage:\n  pmon3 group [command]\n\nAliases:\n  group, groups\n\nAvailable Commands:\n  assign      Assign group(s) to process(es)\n  create      Create a new group\n  del         Delete a group\n  desc        Show group details and associated processes\n  drop        Delete all processes associated to a group\n  ls          List all groups\n  remove      Remove process(es) from group(s)\n  restart     (Re)start processes by group id or name\n  stop        Stop all processes associated to a group\n\nFlags:\n  -h, --help   help for group\n\nUse \"pmon3 group [command] --help\" for more information about a command.\n```\n\n### Examples\n\nFirst lets create a group\n```\npmon3 group create happac\n```\n\nNext, lets assign it to processes with ids 3 and 4\n```\npmon3 group assign happac 3,4\n```\n\nNow, lets confirm that it was associated to the correct processes:\n```\npmon3 group desc happac\n```\n![Screenshot Groups Desc](https://github.com/user-attachments/assets/446dbb6d-0ae5-47d2-bf99-6b5d9c314428)\n\nOops, process 4 should not be associated with the happac group, lets remove the association:\n```\npmon3 group remove happac 4\n```\n\nThis group is no longer useful, lets delete it while keeping the processes intact:\n```\npmon3 group del happac\n```\n\n### Reloading Process Configuration Changes\n\nIf you make a change to the group in the [Process Configuration](#section_processconfig) while pmond is running, you can make the changes take effect by running the `init` command. The `init` command should not restart processes which are already running but it will apply changes from the `process_config_file`.\n```\npmon3 init\n```\n\n\u003ca name=\"section_events\"\u003e\u003c/a\u003e\n## Event Handling With Custom Scripts\n\n```yaml\nevent_handling:\n  # a script to execute when a process is restarted which accepts the process details json as the first argument\n  process_restart:\n  # a script to execute when a process fails (--no-autorestart) which accepts the process details json as the first argument\n  process_failure:\n  # a script to execute when a process backs off when flap detection is enabled\n  process_backoff:\n```\n\n### 1. Specify the executable script to run for the `process_restart` value. `pmond` will pass a json-escaped string of the process details as the first argument.\n#### /etc/pmond/config/config.yml\n```yaml\nevent_handling:\n  # a script to execute when a process is restarted which accepts the process details json as the first argument\n  process_restart: \"/etc/pmon3/bin/on_restart.bash\"\n```\n\n### 2. create the script to accept the json-escaped process details:\n#### /etc/pmon3/bin/on_restart.bash\n```bash\nPROCESS_JSON=\"$1\"\nPROCESS_ID=$(echo \"${PROCESS_JSON}\" | jq '.id')\nPROCESS_NAME=$(echo \"${PROCESS_JSON}\" | jq '.name')\necho \"process restarted: ${PROCESS_ID} - ${PROCESS_NAME}\" \u003e\u003e /var/log/pmond/output.log\n```\n\n### 3. start pmond in debug mode\n```bash \n$ PMON3_DEBUG=true pmond\nINFO/vagrant/go_src/pmon3/pmond/observer/observer.go:29 pmon3/pmond/observer.HandleEvent() Received event: \u0026{restarted 0xc0001da630}\nWARN/vagrant/go_src/pmon3/pmond/observer/observer.go:47 pmon3/pmond/observer.onRestartEvent() restarting process: happac3 (3)\nDEBU/vagrant/go_src/pmon3/pmond/observer/observer.go:70 pmon3/pmond/observer.onEventExec() Attempting event executor(restarted): /etc/pmon3/bin/on_restart.bash \"{\\\"id\\\":3,\\\"created_at\\\":\\\"2024-05-03T05:44:25.114957302Z\\\",\\\"updated_at\\\":\\\"2024-05-03T06:09:18.71222185Z\\\",\\\"pid\\\":4952,\\\"log\\\":\\\"/var/log/pmond/acf3f83.log\\\",\\\"name\\\":\\\"happac3\\\",\\\"process_file\\\":\\\"/usr/local/bin/happac\\\",\\\"args\\\":\\\"-h startup-patroni-1.node.consul -p 5557 -r 5002\\\",\\\"status\\\":2,\\\"auto_restart\\\":true,\\\"uid\\\":1000,\\\"username\\\":\\\"vagrant\\\",\\\"gid\\\":1000}\"\n```\n\n### 4. confirm the script executed successfully\n```bash\n$ tail /var/log/pmond/output.log\nprocess restarted: 4 - \"happac4\"\n```\n\n\u003ca name=\"section_flapping\"\u003e\u003c/a\u003e\n## Flap Detection/Prevention\n\n![Screenshot Backkoff](https://github.com/user-attachments/assets/ec0d482f-9afe-438d-a5fd-18293a5c9ba2)\n\n\nFlap Detection provides the ability to detect processes which are in a perpetually-failed state resulting in excessive restarts which can affect system performance among other things. To prevent excessive restarts you can enable flap detection in the configuration file. You can control the behavior by setting various [threshold parameters](#section_config) which ultimately affect how often a perpetually-failed process can restart within a given time interval.\n\n\n### Enabling\n```yaml\nflap_detection:\n  # enable flap detection\n  is_enabled: true\n```\n\n### Restart Threshold\nDefaulted to `5`, is the amount of process restarts before the flap prevention process begins at which point the process will cease restarts and enter the backoff state.\n```yaml\nflap_detection:\n  # the amount of times a process can restart (within the countdown threshold) until backoff evaluation begins\n  threshold_restarted: 5\n```\n\n### Countdown Threshold\nDefaulted to `120`, is the amount of process monitor intervals until the flap prevention process (backoff state) ends and the process (if still in a perpetually failed state) will resume restarting as normal until the restart threshold is met again. The process monitor interval can also be set in the [configuration file](#section_config) which would affect the time in which it would take to countdown back to zero.\n```yaml\nflap_detection:\n  # the amount of process monitor intervals during a processes backoff period until process evaluation proceeds as normal\n  threshold_countdown: 120\n```\n\n### Decrement Threshold\nDefaulted to `60`, disabled with `0`, is the amount of process monitor intervals during the flap prevention process (backoff state) until the internal process restart counter is decremented. This can affect how the countdown is reached effectively staggering process restarts during the countdown process. This is useful when you don't want to completely back off and allow for intermittent restarts during the flap prevention process (backoff state).\n```yaml\nflap_detection:\n  # the amount of process monitor intervals during a processes backoff period until the processes restart counter is decremented. disabled with 0 value.\n  threshold_decrement: 60\n```\n\n### Example \nUsing the defaults provided above: since the process monitor interval defaults to `500` milliseconds, when a process enters the perpetually failed state and restarts the 5th time, it will enter the backoff state. At this point the flap prevention process will begin the countdown from `120` to `0`. Since the process monitor interval is `500` milliseconds, it will take `120` multiplied by `500` milliseconds (`60` seconds).\n\ncaveat: because the decrement threshold is `60`, the internal restart counter will decrement from `5` to `4` after `60` multiplied by `500` milliseconds (`30` seconds). It will restart `30` seconds into the backoff state instead of `60` seconds and continue counting down to `0` until exiting the flap detection process. If the process remains in a perpetually failed state, it will take `5` restarts to repeat this process all over again.\n\n\u003ca name=\"section_debugging\"\u003e\u003c/a\u003e\n## Debugging\n\n### Environment Variables\n\nYou can specify debug verbosity from both the `pmon3` client and the `pmond` daemon process using the `PMON3_DEBUG` environment variable.\n\n```bash\nPMON3_DEBUG=true pmond \n```\n\n`PMON3_DEBUG` accepts the following values:\n* `true`: sets the debug level to debug\n* `debug`: has the same effect as true\n* `info`: sets the debug level to info\n* `warn`: sets the debug level to warn\n* `error`: sets the debug level to error\n\nYou can also debug the underlying IPC library using `QOG_DEBUG=true`\n\n```bash\nXIPC_DEBUG=true PMON3_DEBUG=true pmon3 ls\n```\n\n### Configuration File\n\nYou can set the log level in the yaml configuration file.\n\n##### /etc/pmond/config/config.yml\n```yaml\n#possible values: debug/info/warn/error\n#default value when empty or omitted\nlog_level: \"info\"\n```\n\nIf you do not specify a value, `info` will be the default Logrus level.\n\n\u003ca name=\"section_performance\"\u003e\u003c/a\u003e\n## Performance Prioritization\n\n### CGO_ENABLED=0\n\nBy default, no underlying libraries require CGO. This allows for portability between machines using different versions of GLIBC and also provides easy installation using the [Release Installer](#release_installer) . Benchmarking results have confirmed less memory and CPU utilization compared to using the libraries which do require `CGO_ENABLED=1` provided below:\n\n### Posix MQ\n\nThe `posix_mq` build tag can be provided to swap out the underlying [gipc](https://github.com/nidhhoggr/gipc/) library with [posix_mq](https://github.com/nidhhoggr/posix_mq). The `posix_mq` wrapper does require `CGO_ENABLED=1` and is considerably faster but also consumes slightly more CPU and Memory. To enable `posix_mq` during the build process:\n```bash\nBUILD_FLAGS=\"-tags posix_mq\" make build_cgo\n```\n\n### CGO-based Sqlite\n\nBy default, `pmon3` utilizes an non-CGO version of sqlite which is unnoticably less performant in most circumstances. To enable the CGO version of sqlite:\n```bash\nBUILD_FLAGS=\"-tags cgo_sqlite\" make build_cgo\n```\n\nIt depends on your requirements whether you need one or both. To enable both of these CGO-dependent modules for maximizing overall performance:\n```bash\nBUILD_FLAGS=\"-tags posix_mq,cgo_sqlite\" make build_cgo\n```\n\nOr without using the Makefile:\n```bash\nCGO_ENABLED=1 go build -tags \"posix_mq,cgo_sqlite\" -o bin/pmon3 cmd/pmon3/pmon3.go\nCGO_ENABLED=1 go build -tags \"posix_mq,cgo_sqlite\" -o bin/pmond cmd/pmond/pmond.go\n```\n\n### Unix Sockets\nSignificantly less performant than the default shared memory implementation and posix_mq implementation. It also has the capability of utilizing TCP cockets with additional build flags (currently: `build -tags net,network`).\n\n```bash\nBUILD_FLAGS=\"-tags net\" make build\n```\n\nOr without using the Makefile:\n```bash\nCGO_ENABLED=0 go build -tags net -o bin/pmon3 cmd/pmon3/pmon3.go\nCGO_ENABLED=0 go build -tags net -o bin/pmond cmd/pmond/pmond.go\n```\n\n\u003ca name=\"section_problems\"\u003e\u003c/a\u003e\n## Common Problems\n\n### 1. Log Rotation?\n\n`pmon3` comes with a logrotate configuration file, which by default utilizes the `/var/log/pmond` directory. If you require a custom log path, you can customize `config.yml` and `rpm/pmond.logrotate`\n\n### 2. The process startup parameter must pass the absolute path?\n\nIf there is a path in the parameters you pass, please use the absolute path. The `pmon3` startup process will start a new sandbox environment to avoid environmental variable pollution.\n\n### 3. Command line automation\n\n`pmon3` provides Bash automation. If you find that the command cannot be automatically provided, please install `bash-completion` and exit the terminal to re-enter:\n\n```bash\nsudo yum install -y bash-completion\n```\n\n#### Using ZSH instead of Bash\n```bash\nautoload -U +X compinit \u0026\u0026 compinit\nautoload -U +X bashcompinit \u0026\u0026 bashcompinit\nsudo sh -c \"pmon3 completion zsh \u003e /etc/profile.d/pmon3.sh\"\nsource /etc/profile.d/pmon3.sh\n```\n\n### 4. FATA/vagrant/go_src/pmon3/cmd/pmon3/pmon3.go:27 main.main() pmond must be running\n\nIf you encounter the error above, make sure the `pmond` service has started successfully.\n\n```bash\nsudo systemctl start pmond\n```\n\n### 5. Should I use `sudo` commands?\n\nYou should only use `sudo` to start the `pmond` process which requires superuser privileges due to the required process forking commands. However, the `pmon3` cli should be used *without* `sudo` to ensure that the spawned processes are attached to the correct parent pid. When using `sudo`, the processes will be attached to ppid 1 and as a result, will become orphaned if the `pmond` process exits prematurely. Using `sudo` also prevents non-root users from being able to access the log files. \n\n#### Spawn a new process as the root user\nYou must have sudo privileges to do this for security reasons. The `--user root` flag is redundant because the process is spawned as the calling user by default and commands ran as sudo are called by the root user.\n```bash\nsudo pmon3 exec /usr/local/bin/happac --user root\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnidhhoggr%2Fpmon3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnidhhoggr%2Fpmon3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnidhhoggr%2Fpmon3/lists"}