Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for distributed apps #10

Merged
merged 27 commits into from
Sep 23, 2024
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -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).
59 changes: 50 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.

@@ -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:
@@ -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
@@ -85,6 +113,7 @@ Update your `.gitignore`
*.duckdb.*
```

> [!WARNING]
> ‼️ Please test thoroughly before proceeding to production!

## Documentation
@@ -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`
@@ -156,5 +197,5 @@ There is a plan to build a separate backend to be powered by ClickHouse in order

### 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"

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