Skip to content

Commit

Permalink
0.2.0 (#19)
Browse files Browse the repository at this point in the history
* Add support for distributed apps (#10)
  • Loading branch information
lalabuy948 authored Sep 23, 2024
1 parent 411f9c8 commit 54c4e40
Show file tree
Hide file tree
Showing 121 changed files with 5,417 additions and 215 deletions.
37 changes: 18 additions & 19 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,32 @@ name: Tests

on:
push:
branches: [ "master" ]
branches: ["master"]
pull_request:
branches: [ "master" ]
branches: ["master"]

permissions:
contents: read

jobs:
build:

name: Build and test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Elixir
uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
with:
elixir-version: '1.15.2' # [Required] Define the Elixir version
otp-version: '26.0' # [Required] Define the Erlang/OTP version
- name: Restore dependencies cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- name: Run tests
run: mix test
- uses: actions/checkout@v4
- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: "1.17.2"
otp-version: "26"
- name: Restore dependencies cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- name: Run tests
run: mix test
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
> [!NOTE]
> Please take a look on [releases description](https://github.com/lalabuy948/PhoenixAnalytics/releases).
70 changes: 54 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<a title="View documentation" href="https://hexdocs.pm/phoenix_analytics"><img src="https://img.shields.io/badge/hex.pm-docs-blue.svg" alt="View documentation" /></a>
</p>

![](/github/hero.png)
![](https://raw.githubusercontent.com/lalabuy948/PhoenixAnalytics/master/github/hero.png)

Phoenix Analytics is embedded plug and play tool designed for Phoenix applications. It provides a simple and efficient way to track and analyze user behavior and application performance without impacting your main application's performance and database.

Expand All @@ -30,7 +30,7 @@ by adding `phoenix_analytics` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:phoenix_analytics, "~> 0.1.3"}
{:phoenix_analytics, "~> 0.2"}
]
end
```
Expand All @@ -39,10 +39,31 @@ Update `config/config.exs`

```exs
config :phoenix_analytics,
database_path: System.get_env("DUCK_PATH") || "analytics.duckdb",
duckdb_path: System.get_env("DUCKDB_PATH") || "analytics.duckdb",
app_domain: System.get_env("PHX_HOST") || "example.com"
```

> [!IMPORTANT]
> In case you have dynamic cluster, you can use your PostgresDB as backend.
```exs
config :phoenix_analytics,
duckdb_path: System.get_env("DUCKDB_PATH") || "analytics.duckdb",
app_domain: System.get_env("PHX_HOST") || "example.com",
postgres_conn: System.get_env("POSTGRES_CONN") || "dbname=postgres user=phoenix password=analytics host=localhost"
```

> [!IMPORTANT]
> In case you would like to proceed with Postgres option, consider enabling caching.
```exs
config :phoenix_analytics,
duckdb_path: System.get_env("DUCKDB_PATH") || "analytics.duckdb",
app_domain: System.get_env("PHX_HOST") || "example.com",
postgres_conn: System.get_env("POSTGRES_CONN") || "dbname=postgres user=phoenix password=analytics host=localhost",
cache_ttl: System.get_env("CACHE_TTL") || 120 # seconds
```

Add migration file

> In case you have ecto less / no migrations project you can do the following:
Expand All @@ -53,8 +74,15 @@ Add migration file
mix ecto.gen.migration add_phoenix_analytics
```

> [!TIP]
> Based on your configuration migration will be run in appropriate database.
> If only `duckdb_path` then in duckdb file.
> If `duckdb_path` and `postgres_conn` provided then in your Postgres database.
```elixir
defmodule MyApp.Repo.Migrations.AddPhoenixAnalytics do
use Ecto.Migration

def up, do: PhoenixAnalytics.Migration.up()
def down, do: PhoenixAnalytics.Migration.down()
end
Expand Down Expand Up @@ -85,6 +113,7 @@ Update your `.gitignore`
*.duckdb.*
```

> [!WARNING]
> ‼️ Please test thoroughly before proceeding to production!
## Documentation
Expand Down Expand Up @@ -119,19 +148,31 @@ mix setup
Then you would need some database with seeds. Here is command for this:

```sh
DUCK_PATH="dev.duckdb" mix run priv/repo/seeds.exs
DUCKDB_PATH="analytics.duckdb" mix run priv/repo/seeds.exs
```

Lastly you can start dev server:
or if you would like to test with Postgres backend:

```sh
DUCK_PATH="dev.duckdb" elixir priv/repo/dev.exs
cd examples/duck_postgres/

docker compose -f postgres-compose.yml up

# from project root
mix run priv/repo/seeds_postgres.exs
```

or
> [!NOTE]
> Move database with seeds to example project which you going to use.
Lastly you can use one of example applications to start server.

```sh
DUCK_PATH="dev.duckdb" iex priv/repo/dev.exs
cd examples/duck_only/

mix deps.get

mix phx.server
```

You can navigate to `http://localhost:4000/dev/analytics`
Expand All @@ -147,14 +188,11 @@ Script can be found here: `vegeta/vegeta.sh`

## For whom this library

- [x] Single instance Phoenix app
- [x] Multiple instances of Phoenix app without auto scaling group

- [ ] Multiple instances of Phoenix app **with** auto scaling group

There is a plan to build a separate backend to be powered by ClickHouse in order to track requests across multiple nodes in orchestrated scenarios.
- [x] Single instance Phoenix app (duckdb only recommended)
- [x] Multiple instances of Phoenix app **without** auto scaling group (duckdb or postgres option can be used)
- [x] Multiple instances of Phoenix app **with** auto scaling group (only postgres powered apps supported at the moment)

### Heavily inspired by

- [https://github.com/elixir-error-tracker/error-tracker](https://github.com/elixir-error-tracker/error-tracker)
- [https://plausible.io](https://plausible.io)
- [error-tracker](https://github.com/elixir-error-tracker/error-tracker)
- [plausible.io](https://plausible.io)
5 changes: 4 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import Config

config :phoenix_analytics,
database_path: System.get_env("DUCK_PATH") || "analytics.duckdb",
duckdb_path: System.get_env("DUCKDB_PATH") || "analytics.duckdb",
app_domain: System.get_env("PHX_HOST") || "example.com"

# postgres_conn: "dbname=postgres user=phoenix password=analytics host=localhost"
# cache_ttl: System.get_env("CACHE_TTL") || 120 # seconds

import_config "#{config_env()}.exs"
2 changes: 2 additions & 0 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Config

config :phoenix_analytics, duckdb_path: System.get_env("DUCKDB_PATH") || "analytics.duckdb"

config :esbuild, :version, "0.17.11"
config :tailwind, :version, "3.2.7"

Expand Down
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import Config

config :phoenix_analytics, database_path: "test.duckdb"
config :phoenix_analytics, duckdb_path: "test.duckdb"
15 changes: 15 additions & 0 deletions docker/minio-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
services:
minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_storage:/data
environment:
MINIO_ROOT_USER: phoenix
MINIO_ROOT_PASSWORD: analytics
command: server --console-address ":9001" /data

volumes:
minio_storage: {}
11 changes: 11 additions & 0 deletions docker/postgres-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
database:
image: "postgres:14.13-alpine"

ports:
- 5432:5432

environment:
POSTGRES_USER: phoenix
POSTGRES_PASSWORD: analytics
POSTGRES_DB: postgres
5 changes: 5 additions & 0 deletions examples/duck_only/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
import_deps: [:phoenix],
plugins: [Phoenix.LiveView.HTMLFormatter],
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}"]
]
39 changes: 39 additions & 0 deletions examples/duck_only/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where 3rd-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Temporary files, for example, from tests.
/tmp/

# Ignore package tarball (built via "mix hex.build").
duck_only-*.tar

# Ignore assets that are produced by build tools.
/priv/static/assets/

# Ignore digested assets cache.
/priv/static/cache_manifest.json

# In case you use Node.js/npm, you want to ignore these.
npm-debug.log
/assets/node_modules/

*.duckdb
*.duckdb.*
57 changes: 57 additions & 0 deletions examples/duck_only/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Duck_Only

## Installation

If [available in Hex](https://hex.pm/packages/phoenix_analytics), the package can be installed
by adding `phoenix_analytics` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:phoenix_analytics, "~> 0.1.2"}
]
end
```

Update `config/config.exs`

```exs
config :phoenix_analytics,
duckdb_path: System.get_env("DUCKDB_PATH") || "analytics.duckdb",
app_domain: System.get_env("PHX_HOST") || "example.com"
```

Add plug to enable tracking to `endpoint.ex`, ‼️ add it straight after your `Plug.Static`

```elixir
plug PhoenixAnalytics.Plugs.RequestTracker
```

Add dashboard route to your `router.ex`

```elixir
use PhoenixAnalytics.Web, :router

phoenix_analytics_dashboard "/analytics"
```

Update your `.gitignore`

```.gitignore
*.duckdb
*.duckdb.*
```

## Start Server

Install dependancies

```sh
mix deps.get
```

Run server

```sh
mix phx.server
```
5 changes: 5 additions & 0 deletions examples/duck_only/assets/css/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

/* This file is for your main application CSS */
44 changes: 44 additions & 0 deletions examples/duck_only/assets/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
// import "../vendor/some-package.js"
//
// Alternatively, you can `npm install some-package --prefix assets` and import
// them using a path starting with the package name:
//
// import "some-package"
//

// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar"

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500,
params: {_csrf_token: csrfToken}
})

// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())

// connect if there are any LiveViews on the page
liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket

Loading

0 comments on commit 54c4e40

Please sign in to comment.