Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions InfoLogger/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Default ignore everything
*

# Project
!lib/
!package*.json
!public/
!index.js
!test/
!eslint.config.js
!config.js
65 changes: 65 additions & 0 deletions InfoLogger/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#
# ---- Base ----
FROM node:22-alpine AS base

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

# Create app directory
WORKDIR /home/node/app

#
# ---- Development Dependencies ----
FROM base AS developmentdependencies

# Installs Git and packages required for Puppeteer
# https://pkgs.alpinelinux.org/packages
RUN apk add --no-cache \
chromium \
freetype \
freetype-dev

# Tell Puppeteer to skip installing Chrome. We'll be using the installed package.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

# Copy all files, except those ignored by .dockerignore, to the container
COPY package*.json ./
# Installs modules from package-lock.json if there are changes, this ensures reproducible build
RUN npm --silent ci


#
# ---- Development ----
FROM developmentdependencies AS development

# Expose the port to the Docker instance (not the host!)
EXPOSE 8080

# Run the container as a non-root user 1000:1000, which is the default user in the node:22-alpine image
USER 1000:1000

# Run start script as specified in package.json
CMD [ "npm", "run", "start:dev" ]

#
# ---- Test ----
FROM developmentdependencies AS test

#
COPY . .

USER 1000:1000

# Run start script as specified in package.json
CMD [ "npm", "run", "test" ]

#
# ---- Simul ----
FROM base AS simul
COPY package.json ./
COPY test/live-simulator ./test/live-simulator
EXPOSE 6102

USER 1000:1000

CMD [ "npm", "run", "simul" ]
93 changes: 43 additions & 50 deletions InfoLogger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- [Interface User Guide](#interface-user-guide)
- [Requirements](#requirements)
- [Project Layout](#project-layout)
- [Scripts](#scripts)
- [Docker development](#docker-development)
- [Backend](#backend)
- [Frontend](#frontend)
- [Local Development](#local-development)
Expand Down Expand Up @@ -55,12 +57,41 @@ Screenshot of the current interface, running locally against a fake InfoLoggerSe
## Requirements

- `nodejs` >= `22.x`
- Docker/Docker Compose
- InfoLogger MariaDB database for Query mode
- InfoLoggerServer endpoint for Live mode

## Project Layout

ILG is a Node.js API Gateway and Single-Page Application built on top of the `@aliceo2/web-ui` framework. It serves as a unified interface to two separate operational backends: a **MariaDB database** for historical queries and an **InfoLoggerServer TCP endpoint** for live log streaming.
## Scripts
| Script | Description |
| --- | --- |
| `npm start` | Run the app (`node index.js`). |
| `npm run lint` | Lint the project with ESLint. |
| `npm run lint:fix` | Lint and automatically fix fixable problems. |
| `npm test` | Run the linter, then the Mocha test suite. |
| `npm run coverage` | Run the test suite under `nyc` and generate the coverage report. |
| `npm run coverage:report` | Generate HTML + JSON coverage reports under `coverage/` from the last run. |

Docker commands (`docker:dev`, `docker:dev:local-live`, `docker:dev:local-query`, `docker:dev:local-both`, `docker:test` and `docker:cleanup`) are documented under [Docker development](#docker-development).

### Docker development

The development and test docker image will take up about 1.35 GB, about 50% of that is due to puppeteer's chromium requirement, the same reason why Electron apps are so big.

`database` and `simulator` are behind Compose profiles, so they only start when you ask for them. Rather than typing `--profile` flags by hand, use one of:

| Script | Application | Database | Simulator |
| --- | --- | --- | --- |
| `npm run docker:dev` | ✅ | ❌ | ❌ |
| `npm run docker:dev:local-live` | ✅ | ❌ | ✅ |
| `npm run docker:dev:local-query` | ✅ | ✅ | ❌ |
| `npm run docker:dev:local-both` | ✅ | ✅ | ✅ |

For services with a cross, point `config.js` at a remote host and port. For services with a checkmark, the script will start a local container for you.

Run `npm run docker:cleanup` to remove all containers created by the above and their data.

## Backend

Expand Down Expand Up @@ -93,72 +124,34 @@ cp config-default.js config.js

Edit `config.js` for the setup you're using below.

`npm run dev` runs the backend under nodemon. The frontend has no hot reload - refresh the browser to pick up changes.

### Query & Live mode Against a remote backend (e.g. a staging instance)

1. Point `mysql` and `infoLoggerServer` in `config.js` at the remote host and port.
2. `npm start`, then open [http://localhost:8080](http://localhost:8080).
1. Point `mysql` and `infoLoggerServer` in `config.js` at a remote host and port. Ask your team for the correct values if you don't have them.
2. `npm run docker:dev`, then open [http://localhost:8080](http://localhost:8080).

### Live mode against synthetic logs (thoroughly test Live mode)

The bundled [fake InfoLoggerServer](test/live-simulator/) emits a log every 0-100 ms, shuffling through [test/live-simulator/fakeData.json](test/live-simulator/fakeData.json).

1. Set `infoLoggerServer` in `config.js` to `localhost:6102`.
2. Terminal 1: `npm run simul`.
3. Terminal 2: `npm run dev`.
4. Open [http://localhost:8080](http://localhost:8080) and click **Live**.
1. Point `infoLoggerServer` in `config.js` at `simulator`.
2. `npm run docker:dev:local-live`.
3. Open [http://localhost:8080](http://localhost:8080) and click **Live**.

### Query against a local DB

Requires [Docker Desktop](https://www.docker.com/products/docker-desktop/).

1. In a working dir, create `compose.yaml`:

```yaml
services:
mariadb:
image: mariadb
restart: unless-stopped
ports: ['3306:3306']
environment:
MARIADB_ROOT_PASSWORD: root # this is just an example, not intended to be a production configuration
phpmyadmin:
image: phpmyadmin
restart: unless-stopped
ports: ['9090:80']
environment:
- PMA_HOST=mariadb
```

Gives you a MariaDB server with phpMyAdmin on the latest image. Pin a specific version (e.g. `mariadb:11.5`) by changing the `image:` tag.

2. `docker compose up -d`.
3. Open [http://localhost:9090/](http://localhost:9090/) → log in `root` / `root` → **New** → create database `INFOLOGGER`.
4. Open the **SQL** tab, paste [docs/database-specs.sql](docs/database-specs.sql), click **Go**.
5. In `config.js`:

```js
mysql: {
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'INFOLOGGER',
port: 3306,
timeout: 60000,
retryMs: 5000,
},
```

6. `npm run dev` - startup should log `Connection to DB successfully established: 127.0.0.1:3306`.
1. Point `mysql` in `config.js` at `database`.
2. `npm run docker:dev:local-query`.
3. Open [http://localhost:8080](http://localhost:8080) and click **Query**.

Need both at once? `npm run docker:dev:local-both` starts the simulator and the local DB together.

## Testing

- `npm test` - eslint + mocha. `npm run mocha` runs the suite alone.
- `npm run docker:test` - eslint + mocha.
- Backend tests: [test/lib/](test/lib).
- Frontend tests: [test/public/](test/public).
- Add or update the matching test when fixing a bug.
- `npm run eslint` - config in [eslint.config.js](eslint.config.js). Lint failures block CI.
- Lint failures block CI.

### Integration tests (live elsewhere)

Expand Down
4 changes: 2 additions & 2 deletions InfoLogger/config-default.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
// optional data source, comment object if not used
// all options: https://github.com/mysqljs/mysql#connection-options
mysql: {
host: '127.0.0.1',
host: process.env.mariadb_host ?? '127.0.0.1',
user: 'root',
password: 'root',
database: 'INFOLOGGER',
Expand All @@ -40,7 +40,7 @@ module.exports = {
// optional data source, comment object if not used
// all options: https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener
infoLoggerServer: {
host: 'localhost',
host: process.env.infologger_host ?? 'localhost',
port: 6102,
},
logging: {
Expand Down
78 changes: 78 additions & 0 deletions InfoLogger/docker-compose.dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
services:
application:
build:
target: development

restart: "no"

depends_on:
database:
condition: service_healthy
required: false
simulator:
condition: service_started
required: false

environment:
NODE_ENV: development

ports:
- "8080:8080"

volumes:
- type: bind
read_only: true
source: ./lib
target: /home/node/app/lib
- type: bind
read_only: true
source: ./public
target: /home/node/app/public
- type: bind
read_only: true
source: ./config.js
target: /home/node/app/config.js
- type: bind
read_only: true
source: ./index.js
target: /home/node/app/index.js

database:
image: mariadb:11.6.2
restart: unless-stopped

environment:
MYSQL_ROOT_PASSWORD: ilPwdB
MYSQL_USER: infoBrowser
MYSQL_PASSWORD: ilPwdB
MYSQL_DATABASE: INFOLOGGER

# should you want to access the DB using a external program
ports:
- "3306:3306"

# MariaDB re-applies INFOLOGGER.sql each time (throwaway dev database).
volumes:
- type: bind
read_only: true
source: ./docker/INFOLOGGER.sql
target: /docker-entrypoint-initdb.d/INFOLOGGER.sql

healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 5s
timeout: 20s
retries: 20

profiles: ['local-db']

simulator:
build:
target: simul

restart: "unless-stopped"

ports:
- "6102:6102"

profiles: ['local-ilg']
9 changes: 9 additions & 0 deletions InfoLogger/docker-compose.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
application:
build:
target: test

restart: "no"

environment:
NODE_ENV: development
5 changes: 5 additions & 0 deletions InfoLogger/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
services:
application:
build:
context: .
dockerfile: Dockerfile
Loading
Loading