-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 73473aa
Showing
14 changed files
with
647 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Used by "mix format" | ||
[ | ||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
name: CI | ||
|
||
on: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-20.04 | ||
env: | ||
MIX_ENV: test | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- pair: | ||
elixir: 1.15.0 | ||
otp: 26.0.1 | ||
lint: lint | ||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- uses: erlef/setup-beam@v1 | ||
with: | ||
otp-version: ${{matrix.pair.otp}} | ||
elixir-version: ${{matrix.pair.elixir}} | ||
|
||
- name: Install Dependencies | ||
run: mix deps.get --only test | ||
|
||
- run: mix format --check-formatted | ||
if: ${{ matrix.lint }} | ||
|
||
- run: mix deps.get && mix deps.unlock --check-unused | ||
if: ${{ matrix.lint }} | ||
|
||
- run: mix deps.compile | ||
|
||
- run: mix compile --warnings-as-errors | ||
if: ${{ matrix.lint }} | ||
|
||
- run: mix credo | ||
|
||
- run: mix test | ||
|
||
- run: mix dialyzer --unmatched_returns |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/_build | ||
/cover | ||
/deps | ||
/doc | ||
/.fetch | ||
erl_crash.dump | ||
*.ez | ||
*.beam | ||
/config/*.secret.exs | ||
.elixir_ls/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Changelog for Jop | ||
|
||
|
||
|
||
## v0.1.0 (2023-12-02) | ||
|
||
* First release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# JOP: an in-memory key value logger | ||
[![Test](https://github.com/bougueil/jop_ex/actions/workflows/ci.yml/badge.svg)](https://github.com/bougueil/jop_ex/actions/workflows/ci.yml) | ||
|
||
Logs in memory, spatially and temporally, key value events.<br> | ||
These events, generated by multiple processes, are then flushed to disk for analysis (e.g. to detect locks). | ||
|
||
|
||
## Installation | ||
|
||
|
||
```elixir | ||
def deps do | ||
[ | ||
{:jop_ex, git: "https://github.com/bougueil/jop_ex"} | ||
] | ||
end | ||
``` | ||
|
||
## Usage | ||
``` | ||
iex> "myjop" | ||
...> |> Jop.init() | ||
...> |> Jop.log("key_1", :any_term_112) | ||
...> |> Jop.log("key_2", :any_term_133) | ||
...> |> Jop.flush() | ||
log stored in jop_myjop.2020_05_12_21.42.49_dates.gz | ||
log stored in jop_myjop.2020_05_12_21.42.49_keys.gz | ||
#Jop<myjop:uninitialized> | ||
``` | ||
|
||
## Performance | ||
Excerpt from a run of the unit test : | ||
``` | ||
througput 1267456 logs/s. | ||
``` | ||
|
||
## Basic example | ||
``` | ||
# prepare for logging and return a handle | ||
myjop = Jop.init("myjop") | ||
# log with handle event "key_1", :any_term_112 | ||
Jop.log myjop, "key_1", :any_term_112 | ||
Process.sleep 12 | ||
# clear logs | ||
Jop.clear myjop | ||
Jop.log myjop, "key_2", :any_term_113 | ||
Process.sleep 12 | ||
Jop.log myjop, "key_1", :any_term_112 | ||
Process.sleep 12 | ||
Jop.log myjop, "key_2", :any_term_113 | ||
# flush to disk and erase the log | ||
Jop.flush myjop | ||
log stored in jop_myjop.2020_05_12_21.42.49_dates.gz | ||
log stored in jop_myjop.2020_05_12_21.42.49_keys.gz | ||
#Jop<myjop:uninitialized> | ||
``` | ||
will generate both a temporal (by date) and a spatial (by key) log files: | ||
|
||
### Temporal log file | ||
``` | ||
# list all operations by date | ||
zcat jop_myjop.2020_05_12_21.42.49_dates.gz | ||
00:00:00_000.482 "key_2": :any_term_113 | ||
00:00:00_014.674 "key_1": :any_term_112 | ||
00:00:00_028.568 "key_2": :any_term_113 | ||
``` | ||
|
||
### Spatial (by key) log file | ||
``` | ||
# list all operations by key : | ||
zcat jop_myjop.2020_05_12_21.42.49_keys.gz | ||
"key_1": 00:00:00_014.674 :any_term_112 | ||
"key_2": 00:00:00_000.482 :any_term_113 | ||
"key_2": 00:00:00_028.568 :any_term_113 | ||
``` | ||
## Real life: multiple processes logging | ||
Processes log in myjop as follow: | ||
``` | ||
# Handle can be saved in process state | ||
myjop = Jop.ref("myjop") | ||
# Log if logging is activated | ||
Jop.log myjop, "key_1", :any_term_112 | ||
``` | ||
Console activate / deactivate the logging: | ||
``` | ||
# Activate the logging | ||
# Starts the logging | ||
myjop = Jop.init("myjop") | ||
# Do some queries while the logging is on | ||
inspect myjop # see how many records | ||
Enum.count mylog | ||
Enum.member? mylog, "mykey" | ||
... | ||
# Flush the logs on disk, keep on logging | ||
Jop.flush myjop, :nostop | ||
# Clear the logs, keep on logging | ||
Jop.clear myjop # clear all entries and continue logging | ||
# Flush the logs on disk and deactivate the logging | ||
Jop.flush myjop | ||
# Start logging again | ||
Jop.init("myjop") | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import Config | ||
|
||
# https://spapas.github.io/2020/05/15/elixir-osmon-alerts/ | ||
# config :os_mon, | ||
# memsup_system_only: true, | ||
# start_disk_sup: false, | ||
# start_cpu_sup: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# See LICENSE for licensing information. | ||
|
||
defmodule JLValid do | ||
@moduledoc false | ||
|
||
defmacro ets?(tab, clauses) do | ||
valid_if(tab, clauses) | ||
end | ||
|
||
defp valid_if(tab, do: do_clause) do | ||
valid_if(tab, do: do_clause, else: nil) | ||
end | ||
|
||
defp valid_if(tab, do: do_clause, else: else_clause) do | ||
quote do | ||
case :undefined != :ets.info(unquote(tab), :size) do | ||
x when :"Elixir.Kernel".in(x, [false, nil]) -> unquote(else_clause) | ||
_ -> unquote(do_clause) | ||
end | ||
end | ||
end | ||
end | ||
|
||
defmodule JLCommon do | ||
@moduledoc false | ||
|
||
@date_format ".~p_~2.2.0w_~2.2.0w_~2.2.0w.~2.2.0w.~2.2.0w" | ||
|
||
def date_str do | ||
hms = | ||
List.flatten( | ||
for e <- Tuple.to_list(:calendar.universal_time_to_local_time(:calendar.universal_time())) do | ||
Tuple.to_list(e) | ||
end | ||
) | ||
|
||
:io_lib.format(@date_format, hms) | ||
end | ||
end |
Oops, something went wrong.