Current section

20 Versions

Jump to

Compare versions

19 files changed
+270 additions
-899 deletions
  @@ -3,4 +3,47 @@
3 3 [![Package Version](https://img.shields.io/hexpm/v/spectator)](https://hex.pm/packages/spectator)
4 4 [![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/spectator/)
5 5
6 - This is the code for the spectator package, published on hex.
\ No newline at end of file
6 + Spectator is a BEAM observer tool written in Gleam, that plays well with gleam_otp processes.
7 +
8 + This is the spectator package, published on hex, which allows you to run spectator from within your application, which is useful for **development**.
9 +
10 + If you want to use spectator to inspect a deployed **production** application instead, please see [the main README](https://github.com/JonasGruenwald/spectator/blob/main/README.md#use-spectator-in-production).
11 +
12 + ## Use Spectator in Development
13 +
14 + ```sh
15 + gleam add spectator
16 + ```
17 +
18 + Call `spectator.start()` in your application, to start the spectator service and WebUI.
19 +
20 + In order to make it easier to identify your Gleam processes in the process list, you can tag them with a friendly name with `spectator.tag`, `spectator.tag_subject` or `spectator.tag_result` **after** starting the spectator service.
21 +
22 + ```gleam
23 + import gleam/erlang/process
24 + import spectator
25 + import utils/pantry
26 +
27 + pub fn main() {
28 + // Start the spectator service
29 + let assert Ok(_) = spectator.start()
30 +
31 + // Start an OTP actor
32 + let assert Ok(sub) = pantry.new()
33 +
34 + // Tag the actor with a name for easier identification in the spectator UI
35 + // Note: this only works because we called spectator.start before!
36 + sub
37 + |> spectator.tag_subject("Pantry Actor")
38 +
39 + // Add some state to the actor
40 + pantry.add_item(sub, "This actor has some state")
41 + pantry.add_item(sub, "Another item in the state of this actor")
42 + pantry.add_item(sub, "And some more state I've put into this demo actor")
43 +
44 + // Sleep on the main process so the program doesn't exit
45 + process.sleep_forever()
46 + }
47 + ```
48 +
49 + For an overview of spectator itself, please see [the main README](https://github.com/JonasGruenwald/spectator/blob/main/README.md).
  @@ -1,15 +1,15 @@
1 1 name = "spectator"
2 - version = "2.0.0"
2 + version = "2.0.1"
3 3 description = "BEAM observer tool"
4 4 licences = ["MIT"]
5 - repository = { type = "github", user = "JonasGruenwald", repo = "spectator" }
5 + repository = { type = "github", user = "JonasGruenwald", repo = "spectator", path = "spectator" }
6 6
7 7 [documentation]
8 8 pages = [
9 9 { title = "Changelog", path = "changelog.html", source = "../CHANGELOG.md" },
10 + { title = "About Spectator", path = "overview.html", source = "../README.md" },
10 11 ]
11 12
12 -
13 13 [dependencies]
14 14 simplifile = ">= 2.2.0 and < 3.0.0"
15 15 pprint = ">= 1.0.3 and < 2.0.0"
  @@ -25,3 +25,4 @@ lustre = ">= 5.0.0 and < 6.0.0"
25 25 [dev-dependencies]
26 26 gleeunit = ">= 1.0.0 and < 2.0.0"
27 27 carpenter = { git = "https://github.com/ghivert/carpenter.git", ref = "main" }
28 + embeds = ">= 1.1.2 and < 2.0.0"
  @@ -1,6 +1,6 @@
1 1 {<<"name">>, <<"spectator">>}.
2 2 {<<"app">>, <<"spectator">>}.
3 - {<<"version">>, <<"2.0.0">>}.
3 + {<<"version">>, <<"2.0.1">>}.
4 4 {<<"description">>, <<"BEAM observer tool"/utf8>>}.
5 5 {<<"licenses">>, [<<"MIT">>]}.
6 6 {<<"build_tools">>, [<<"gleam">>]}.
  @@ -13,20 +13,20 @@
13 13 {<<"optional">>, false},
14 14 {<<"requirement">>, <<">= 5.0.0 and < 6.0.0">>}
15 15 ]},
16 - {<<"logging">>, [
17 - {<<"app">>, <<"logging">>},
16 + {<<"pprint">>, [
17 + {<<"app">>, <<"pprint">>},
18 18 {<<"optional">>, false},
19 - {<<"requirement">>, <<">= 1.3.0 and < 2.0.0">>}
19 + {<<"requirement">>, <<">= 1.0.3 and < 2.0.0">>}
20 20 ]},
21 - {<<"gleam_erlang">>, [
22 - {<<"app">>, <<"gleam_erlang">>},
21 + {<<"gleam_otp">>, [
22 + {<<"app">>, <<"gleam_otp">>},
23 23 {<<"optional">>, false},
24 24 {<<"requirement">>, <<">= 1.0.0 and < 2.0.0">>}
25 25 ]},
26 - {<<"gleam_stdlib">>, [
27 - {<<"app">>, <<"gleam_stdlib">>},
26 + {<<"gleam_http">>, [
27 + {<<"app">>, <<"gleam_http">>},
28 28 {<<"optional">>, false},
29 - {<<"requirement">>, <<">= 0.65.0 and < 1.0.0">>}
29 + {<<"requirement">>, <<">= 4.0.0 and < 5.0.0">>}
30 30 ]},
31 31 {<<"mist">>, [
32 32 {<<"app">>, <<"mist">>},
  @@ -38,25 +38,25 @@
38 38 {<<"optional">>, false},
39 39 {<<"requirement">>, <<">= 3.0.0 and < 4.0.0">>}
40 40 ]},
41 - {<<"pprint">>, [
42 - {<<"app">>, <<"pprint">>},
41 + {<<"logging">>, [
42 + {<<"app">>, <<"logging">>},
43 43 {<<"optional">>, false},
44 - {<<"requirement">>, <<">= 1.0.3 and < 2.0.0">>}
44 + {<<"requirement">>, <<">= 1.3.0 and < 2.0.0">>}
45 45 ]},
46 - {<<"gleam_http">>, [
47 - {<<"app">>, <<"gleam_http">>},
46 + {<<"gleam_stdlib">>, [
47 + {<<"app">>, <<"gleam_stdlib">>},
48 48 {<<"optional">>, false},
49 - {<<"requirement">>, <<">= 4.0.0 and < 5.0.0">>}
49 + {<<"requirement">>, <<">= 0.65.0 and < 1.0.0">>}
50 + ]},
51 + {<<"gleam_erlang">>, [
52 + {<<"app">>, <<"gleam_erlang">>},
53 + {<<"optional">>, false},
54 + {<<"requirement">>, <<">= 1.0.0 and < 2.0.0">>}
50 55 ]},
51 56 {<<"simplifile">>, [
52 57 {<<"app">>, <<"simplifile">>},
53 58 {<<"optional">>, false},
54 59 {<<"requirement">>, <<">= 2.2.0 and < 3.0.0">>}
55 - ]},
56 - {<<"gleam_otp">>, [
57 - {<<"app">>, <<"gleam_otp">>},
58 - {<<"optional">>, false},
59 - {<<"requirement">>, <<">= 1.0.0 and < 2.0.0">>}
60 60 ]}
61 61 ]}.
62 62 {<<"files">>, [
  @@ -86,13 +86,12 @@
86 86 <<"include/spectator@internal@components@processes_live_Model.hrl">>,
87 87 <<"include/spectator@internal@components@processes_live_ReceivedOtpDetails.hrl">>,
88 88 <<"include/spectator@internal@views@charts_ChartSegment.hrl">>,
89 - <<"priv/connect-widget.js">>,
90 - <<"priv/lucy_spectator.svg">>,
91 - <<"priv/styles.css">>,
92 89 <<"src/spectator.app.src">>,
93 90 <<"src/spectator.erl">>,
94 91 <<"src/spectator.gleam">>,
95 92 <<"src/spectator/internal/api.gleam">>,
93 + <<"src/spectator/internal/assets.gleam">>,
94 + <<"src/spectator/internal/assets/connect-widget.js">>,
96 95 <<"src/spectator/internal/common.gleam">>,
97 96 <<"src/spectator/internal/components/dashboard_live.gleam">>,
98 97 <<"src/spectator/internal/components/ets_overview_live.gleam">>,
  @@ -104,6 +103,7 @@
104 103 <<"src/spectator/internal/views/navbar.gleam">>,
105 104 <<"src/spectator/internal/views/table.gleam">>,
106 105 <<"src/spectator@internal@api.erl">>,
106 + <<"src/spectator@internal@assets.erl">>,
107 107 <<"src/spectator@internal@common.erl">>,
108 108 <<"src/spectator@internal@components@dashboard_live.erl">>,
109 109 <<"src/spectator@internal@components@ets_overview_live.erl">>,
  @@ -1,84 +0,0 @@
1 - console.log("Connect widget loaded!");
2 -
3 - const dialogHtml = `
4 - <dialog class="connect-widget-dialog">
5 - <div class="connect-widget-content">
6 - <h2>Inspect BEAM Node</h2>
7 - <div class="connect-widget-form">
8 - <label for="node-name">Node Name</label>
9 - <input required="true" type="text" id="node-name" name="node-address" placeholder="wibble@127.0.0.1" />
10 - <label for="node-cookie">Cookie</label>
11 - <input type="text" id="node-cookie" name="node-cookie" placeholder="wobble" />
12 - <label for="refresh-interval">Refresh Interval</label>
13 - <select id="refresh-interval" name="refresh-interval">
14 - <option value="">Default</option>
15 - <option value="500">500 milliseconds</option>
16 - <option value="1000">1 second</option>
17 - <option value="2000">2 seconds</option>
18 - <option value="5000">5 seconds</option>
19 - <option value="10000">10 seconds</option>
20 - <option value="30000">30 seconds</option>
21 - <option value="60000">1 minute</option>
22 - </select>
23 - </div>
24 - <div class="connect-widget-actions">
25 - <button title="Close this dialog" id="connect-cancel">Cancel</button>
26 - <button title="Inspect the node that spectator itself is running on" id="connect-resetl">Inspect Spectator Node</button>
27 - <button title="Connect to specified node" id="connect-submit">Connect</button>
28 - </div>
29 - </div>
30 - </dialog>
31 - `;
32 -
33 - const template = document.createElement("template");
34 - template.innerHTML = dialogHtml.trim();
35 - const dialogElement = template.content.firstChild;
36 - document.body.appendChild(dialogElement);
37 -
38 - const cancelButton = dialogElement.querySelector("#connect-cancel");
39 - const resetButton = dialogElement.querySelector("#connect-resetl");
40 - const submitButton = dialogElement.querySelector("#connect-submit");
41 - const nodeNameInput = dialogElement.querySelector("#node-name");
42 - const nodeCookieInput = dialogElement.querySelector("#node-cookie");
43 - const refreshIntervalSelect = dialogElement.querySelector("#refresh-interval");
44 -
45 - // Prefill with current params
46 - const urlParams = new URLSearchParams(window.location.search);
47 - const currentNode = urlParams.get("node") || "";
48 - const currentCookie = urlParams.get("cookie") || "";
49 - const currentInterval = urlParams.get("refresh") || "";
50 - nodeNameInput.value = currentNode;
51 - nodeCookieInput.value = currentCookie;
52 - refreshIntervalSelect.value = currentInterval;
53 -
54 - submitButton.addEventListener("click", () => {
55 - const nodeName = nodeNameInput.value;
56 - const nodeCookie = nodeCookieInput.value;
57 - const refreshInterval = refreshIntervalSelect.value;
58 -
59 - if (nodeNameInput.reportValidity()) {
60 - const newParams = new URLSearchParams();
61 - newParams.set("node", nodeName);
62 - if (nodeCookie) {
63 - newParams.set("cookie", nodeCookie);
64 - }
65 - if (refreshInterval !== "") {
66 - newParams.set("refresh", refreshInterval);
67 - }
68 - window.location.search = newParams.toString();
69 - }
70 - });
71 -
72 - cancelButton.addEventListener("click", () => {
73 - dialogElement.close();
74 - });
75 -
76 - resetButton.addEventListener("click", () => {
77 - window.location.search = "";
78 - dialogElement.close();
79 - });
80 -
81 - document.querySelectorAll(".change-target-button").forEach((button) => {
82 - button.style.display = "inline-block";
83 - button.addEventListener("click", dialogElement.showModal.bind(dialogElement));
84 - });
\ No newline at end of file
  @@ -1,36 +0,0 @@
1 - <?xml version="1.0" encoding="utf-8"?>
2 - <svg viewBox="-40.546 -53.577 2251.673 2524.133" fill="none" xmlns="http://www.w3.org/2000/svg"
3 - xmlns:bx="https://boxy-svg.com">
4 - <path
5 - d="M 842.763 1885.449 C 870.851 1965.043 975.268 1983.454 1028.887 1918.269 L 1309.907 1576.606 C 1344.677 1534.33 1396.137 1509.279 1450.877 1507.946 L 1893.517 1497.176 C 1978.027 1495.121 2027.657 1401.679 1982.187 1330.643 L 1743.607 957.976 C 1729.017 935.196 1719.507 909.536 1715.737 882.746 C 1711.957 855.966 1714.007 828.676 1721.737 802.756 L 1848.077 378.926 C 1872.157 298.176 1798.617 221.916 1716.767 243.186 L 1288.287 354.516 C 1262.097 361.326 1234.747 362.416 1208.097 357.716 C 1181.457 353.026 1156.127 342.646 1133.847 327.286 L 769.294 76.116 C 699.65 28.146 604.466 74.646 599.463 158.766 L 573.239 600.246 C 569.994 654.886 543.11 705.386 499.603 738.616 L 147.94 1007.216 C 80.914 1058.41 95.596 1163.196 174.303 1194.032 L 586.57 1355.546 C 637.55 1375.519 677.336 1416.659 695.55 1468.278 L 842.763 1885.449 Z"
6 - fill="#FFAFF3" style="transform-box: fill-box; transform-origin: 50% 50%;"
7 - transform="matrix(-1, 0, 0, -1, 0.000033, 0.000056)" />
8 - <path
9 - d="M 918.91 1994.668 C 868.969 1985.861 823.32 1952.703 804.42 1899.152 L 657.186 1481.986 C 642.831 1441.315 611.52 1408.933 571.327 1393.185 L 159.044 1231.661 C 53.25 1190.213 32.792 1044.7 122.981 975.816 L 474.644 707.246 C 491.576 694.326 505.522 677.906 515.528 659.096 C 525.534 640.296 531.366 619.556 532.625 598.296 L 558.835 156.826 C 565.559 43.566 697.668 -20.864 791.287 43.616 L 791.289 43.626 L 1155.87 294.796 L 1155.87 294.806 C 1173.42 306.906 1193.38 315.086 1214.37 318.786 C 1235.37 322.486 1256.92 321.626 1277.55 316.256 L 1706.04 204.946 C 1816.06 176.356 1918.17 282.096 1885.75 390.836 L 1885.75 390.826 L 1759.42 814.646 C 1753.33 835.056 1751.72 856.536 1754.69 877.636 C 1757.66 898.726 1765.15 918.926 1776.65 936.856 L 1776.65 936.866 L 2015.25 1309.543 L 2015.24 1309.545 C 2076.44 1405.123 2007.46 1534.859 1893.87 1537.622 L 1451.21 1548.375 C 1408.06 1549.423 1367.56 1569.142 1340.17 1602.448 L 1059.15 1944.101 C 1023.08 1987.955 968.841 2003.497 918.896 1994.689 M 932.34 1918.443 C 955.035 1922.445 979.819 1914.605 997.365 1893.277 L 1278.38 1551.634 C 1320.52 1500.393 1382.95 1470.014 1449.26 1468.401 L 1891.92 1457.648 C 1947.35 1456.302 1977.63 1399.16 1947.86 1352.674 L 1709.27 979.996 C 1673.48 924.126 1663.8 855.366 1682.74 791.796 L 1809.08 367.986 C 1824.81 315.206 1779.83 268.436 1726.15 282.376 L 1297.66 393.696 C 1233.45 410.386 1165.09 398.326 1110.46 360.676 L 745.884 109.506 C 700.205 78.036 641.945 106.606 638.676 161.576 L 612.469 603.046 C 608.537 669.276 575.914 730.556 523.186 770.836 L 171.524 1039.406 C 127.662 1072.905 136.58 1136.956 188.203 1157.189 L 600.485 1318.715 C 662.256 1342.917 710.525 1392.816 732.608 1455.385 L 732.608 1455.387 L 879.842 1872.552 C 889.034 1898.593 909.64 1914.438 932.335 1918.441"
10 - fill="#151515" style="transform-box: fill-box; transform-origin: 50% 50%;"
11 - transform="matrix(-1, 0, 0, -1, 0.000013, -0.000111)" />
12 - <path
13 - d="M 1340.734 989.33 C 1383.47 996.87 1412.007 1037.62 1404.473 1080.35 C 1396.939 1123.09 1356.188 1151.617 1313.452 1144.081 C 1270.716 1136.544 1242.179 1095.79 1249.713 1053.06 C 1257.247 1010.33 1297.999 981.79 1340.734 989.33 Z"
14 - fill="#151515" style="transform-box: fill-box; transform-origin: 50% 50%;"
15 - transform="matrix(-1, 0, 0, -1, -0.000262, 0.00008)" />
16 - <path
17 - d="M 707.68 877.704 C 750.41 885.234 778.95 925.99 771.41 968.722 C 763.88 1011.455 723.13 1039.988 680.39 1032.451 C 637.66 1024.915 609.12 984.163 616.65 941.43 C 624.19 898.694 664.94 870.164 707.68 877.704 Z"
18 - fill="#151515" style="transform-box: fill-box; transform-origin: 50% 50%;"
19 - transform="matrix(-1, 0, 0, -1, 0.000102, -0.000003)" />
20 - <path
21 - d="M 908.965 1220.696 C 904.065 1218.806 899.585 1215.966 895.775 1212.346 C 891.975 1208.726 888.915 1204.386 886.795 1199.586 C 884.665 1194.776 883.505 1189.606 883.375 1184.356 C 883.245 1179.106 884.155 1173.876 886.045 1168.976 C 890.985 1156.206 898.385 1144.526 907.835 1134.606 C 917.285 1124.686 928.595 1116.736 941.125 1111.196 L 941.135 1111.186 C 953.645 1105.646 967.125 1102.626 980.815 1102.296 L 980.825 1102.296 L 980.845 1102.296 C 994.525 1101.976 1008.135 1104.346 1020.905 1109.276 L 1020.915 1109.276 C 1033.685 1114.206 1045.365 1121.606 1055.275 1131.056 L 1055.285 1131.056 L 1055.285 1131.066 C 1065.195 1140.506 1073.145 1151.816 1078.685 1164.326 C 1084.245 1176.856 1087.265 1190.366 1087.585 1204.066 C 1087.835 1214.666 1083.865 1224.936 1076.545 1232.616 C 1069.215 1240.286 1059.145 1244.736 1048.535 1244.986 C 1043.285 1245.116 1038.065 1244.196 1033.165 1242.306 C 1028.265 1240.406 1023.785 1237.566 1019.985 1233.936 C 1016.185 1230.316 1013.135 1225.976 1011.015 1221.166 C 1008.895 1216.366 1007.735 1211.186 1007.615 1205.936 C 1007.535 1202.766 1006.835 1199.636 1005.545 1196.736 L 1005.545 1196.726 L 1005.535 1196.706 C 1004.245 1193.796 1002.395 1191.166 1000.095 1188.966 C 997.785 1186.766 995.075 1185.046 992.105 1183.906 L 992.085 1183.896 C 989.105 1182.746 985.935 1182.196 982.745 1182.266 C 979.565 1182.346 976.425 1183.056 973.515 1184.346 L 973.495 1184.346 L 973.485 1184.356 C 970.575 1185.646 967.955 1187.486 965.755 1189.786 L 965.755 1189.796 C 963.555 1192.106 961.835 1194.816 960.685 1197.796 C 958.795 1202.696 955.955 1207.176 952.335 1210.976 C 948.705 1214.776 944.375 1217.836 939.565 1219.956 C 934.765 1222.086 929.585 1223.246 924.335 1223.376 C 919.085 1223.506 913.865 1222.596 908.965 1220.696 Z"
22 - fill="#151515" style="transform-box: fill-box; transform-origin: 50% 50%;"
23 - transform="matrix(-1, 0, 0, -1, 0.000158, -0.000137)" />
24 - <path style="fill: rgb(216, 216, 216); stroke: rgb(0, 0, 0);"
25 - d="M 837.332 1799.273 L 1040.536 1392.732 L 1200.981 1417.848 L 1168.502 1900.5" />
26 - <path style="fill: rgb(216, 216, 216); stroke: rgb(0, 0, 0);"
27 - d="M 1462.463 1851.433 L 1464.166 1415.159 L 1635.88 1406.161 L 1804.306 1841.839" />
28 - <g style="" transform="matrix(5.468584, 0, 0, 5.468584, -10849.720703, -6934.962402)">
29 - <path
30 - d="M 2200.077 1640.391 C 2200.077 1671.183 2166.744 1690.428 2140.077 1675.032 C 2113.41 1659.636 2113.41 1621.146 2140.077 1605.75 C 2146.158 1602.239 2153.055 1600.391 2160.077 1600.391 C 2182.168 1600.391 2200.077 1618.3 2200.077 1640.391 Z M 2288.077 1600.391 C 2257.285 1600.391 2238.04 1633.724 2253.436 1660.391 C 2268.832 1687.058 2307.322 1687.058 2322.718 1660.391 C 2326.229 1654.31 2328.077 1647.412 2328.077 1640.391 C 2328.077 1618.3 2310.168 1600.391 2288.077 1600.391 Z"
31 - opacity="0.2" style="paint-order: fill; fill: rgb(255, 251, 232);" />
32 - <path
33 - d="M 2333.277 1624.261 C 2332.609 1622.397 2331.824 1620.576 2330.927 1618.811 L 2289.337 1524.191 C 2288.943 1523.28 2288.38 1522.452 2287.677 1521.751 C 2275.18 1509.251 2254.914 1509.251 2242.417 1521.751 C 2240.922 1523.248 2240.081 1525.276 2240.077 1527.391 L 2240.077 1552.391 L 2208.077 1552.391 L 2208.077 1527.391 C 2208.079 1525.269 2207.237 1523.233 2205.737 1521.731 C 2193.24 1509.231 2172.974 1509.231 2160.477 1521.731 C 2159.774 1522.432 2159.21 1523.26 2158.817 1524.171 L 2117.227 1618.791 C 2116.33 1620.556 2115.545 1622.377 2114.877 1624.241 C 2102.441 1659.036 2132.336 1694.245 2168.687 1687.617 C 2191.501 1683.457 2208.079 1663.581 2208.077 1640.391 L 2208.077 1568.391 L 2240.077 1568.391 L 2240.077 1640.391 C 2240.058 1677.341 2280.047 1700.456 2312.056 1681.997 C 2332.152 1670.408 2341.084 1646.106 2333.277 1624.261 Z M 2172.787 1532.141 C 2178.268 1527.526 2186.148 1527.118 2192.077 1531.141 L 2192.077 1604.651 C 2179.365 1593.237 2161.537 1589.457 2145.287 1594.731 L 2172.787 1532.141 Z M 2160.077 1672.391 C 2135.443 1672.391 2120.047 1645.724 2132.364 1624.391 C 2144.681 1603.058 2175.473 1603.058 2187.79 1624.391 C 2190.598 1629.256 2192.077 1634.774 2192.077 1640.391 C 2192.077 1658.064 2177.75 1672.391 2160.077 1672.391 Z M 2256.077 1531.131 C 2262.006 1527.108 2269.886 1527.516 2275.367 1532.131 L 2302.867 1594.711 C 2286.615 1589.44 2268.787 1593.223 2256.077 1604.641 L 2256.077 1531.131 Z M 2288.077 1672.391 C 2263.443 1672.391 2248.047 1645.724 2260.364 1624.391 C 2272.681 1603.058 2303.473 1603.058 2315.79 1624.391 C 2318.598 1629.256 2320.077 1634.774 2320.077 1640.391 C 2320.077 1658.064 2305.75 1672.391 2288.077 1672.391 Z"
34 - style="fill: rgb(47, 47, 47);" />
35 - </g>
36 - </svg>
\ No newline at end of file
Loading more files…