From 83b9c0b2d4f9bc5641880e6673facbe1e25c1627 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:45:19 +0000 Subject: [PATCH 1/8] docker comments --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 25a8a86c..14d40a2c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -27,6 +27,6 @@ COPY ["package*.json", "LICENSE", "./"] RUN npm ci --quiet --only=production && npm cache clean --force --silent COPY --from=builder /usr/src/app/build/ ./build -# HEALTHCHECK --interval=30s CMD node healthcheck.js ? +# HEALTHCHECK --interval=30s CMD node healthcheck.js ? or curl localhost/healthz = OK ? ENTRYPOINT [ "/sbin/tini", "--", "node", "build/server.js" ] From 16a60aedbb93751d38d3f33cc399c0a2b4881aa2 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:45:44 +0000 Subject: [PATCH 2/8] logtails module --- src/lib/log-tail.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/lib/log-tail.ts diff --git a/src/lib/log-tail.ts b/src/lib/log-tail.ts new file mode 100644 index 00000000..bd118e7f --- /dev/null +++ b/src/lib/log-tail.ts @@ -0,0 +1,29 @@ +const logTail: string[] = []; +let tailLength = 10; // default + +export function setTailLength(newTailLength: number): void { + if (newTailLength <= 0) { + throw Error("Unexpected tailLength"); + } + tailLength = newTailLength; +} + +export function addInfo(s: string): void { + logTail.push(s); + if (logTail.length > tailLength) { + logTail.shift(); + } +} + +export function getLogTail(): string[] { + return logTail; +} + +export function formatDate(date: Date): string { + return date.toISOString().substr(0, 19).replace("T", " "); +} + +export function addInfoEx(entries: string | string[]): void { + entries = Array.isArray(entries) ? entries : [entries]; + addInfo([ formatDate(new Date()), ...entries ].join(", ")); +} From 3647e9cf310429023da2c025ec676bfbc3e2dcb5 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:46:27 +0000 Subject: [PATCH 3/8] rewire frontend log --- src/api/index.ts | 24 +++++++++++++++--------- src/app.ts | 17 ++++++----------- src/front_page.ts | 14 ++++++++++++-- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index c0038cb2..9f80c8ca 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,5 +1,6 @@ import * as express from "express"; import {checkObject} from "./check_object"; +import { addInfoEx } from "../lib/log-tail"; const router = express.Router(); @@ -7,7 +8,7 @@ router.use(express.json({limit: "50mb"})); router.use(express.urlencoded({limit: "50mb", extended: false})); router.post("/ping", (_req, res) => { - // addInfo("ping, " + new Date()); + addInfoEx("ping"); res.json({ success: true, payload: "abap is forevah!" }); }); @@ -15,13 +16,17 @@ router.post("/check_file", (req, res) => { // TODO validate request // TODO define response type ? // TODO capture exceptions, return json with error + const hrstart = process.hrtime(); const result = checkObject(req.body); - // addInfo("check_file, " + - // result.object.objectType + " " + - // result.object.objectName + ", " + - // result.issues.length + " issues, " + - // new Date() + ", " + - // req.socket.bytesRead + " bytes"); + const hrend = process.hrtime(hrstart); + addInfoEx([ + "check_file", + result.object.objectType, + result.object.objectName, + `${result.issues.length} issues`, + `${req.socket.bytesRead} bytes`, + `${(hrend[0] * 1000 + hrend[1] / 1000000).toFixed()} ms`, + ]); res.json(result); }); @@ -29,8 +34,9 @@ router.post("/check_file", (req, res) => { // app.post("/api/v1/get_default_configuration", // app.post("/api/v1/pretty_print", -router.all("*", (_req, res) => { - return res.status(404).json({ success: false, error: { message: "Wrong API call" } }); +router.all("*", (req, res) => { + addInfoEx("unexpected API call: " + req.originalUrl); + res.status(404).json({ success: false, error: { message: "Wrong API call" } }); }); export default router; diff --git a/src/app.ts b/src/app.ts index 14061be3..376c5770 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,27 +3,22 @@ import * as morgan from "morgan"; import * as helmet from "helmet"; import { frontPage } from "./front_page"; import api from "./api"; +import { addInfoEx } from "./lib/log-tail"; const app = express(); -// const info: string[] = []; - -// function addInfo(s: string): void { -// info.push(s); -// if (info.length > 10) { -// info.shift(); -// } -// } - if (process.env.NODE_ENV !== "test") { // app.use(cors()); app.use(helmet()); app.use(morgan("common")); } -app.get("/", (_req, res) => res.send(frontPage([]))); +app.get("/", (_req, res) => res.send(frontPage())); app.get("/healthz", (_req, res) => res.send("OK")); app.use("/api/v1", api); -app.use("*", (_req, res) => res.status(404).send("forbidden") ); +app.use("*", (req, res) => { + addInfoEx("unexpected request: " + req.originalUrl); + res.status(404).send("forbidden"); +}); export default app; diff --git a/src/front_page.ts b/src/front_page.ts index f6766bf7..d5a146e8 100644 --- a/src/front_page.ts +++ b/src/front_page.ts @@ -1,5 +1,6 @@ import * as abaplint from "@abaplint/core"; import * as os from "os"; +import { getLogTail } from "./lib/log-tail"; function osInfo(): string { return "load: " + os.loadavg() + "
" + @@ -10,7 +11,16 @@ function osInfo(): string { "cpus: " + JSON.stringify(os.cpus()) + "
"; } -export function frontPage(info: string[]): string { +function renderLogTail(): string { + if (process.env.ALB_SUPRESS_FRONPAGE_LOG === "1") { + return ""; + } else { + const info = getLogTail(); + return info.join("
"); + } +} + +export function frontPage(): string { return ` @@ -21,7 +31,7 @@ export function frontPage(info: string[]): string {
${osInfo()}
- ${info.join("
")} + ${renderLogTail()} `; From 11389caa759dc5772c5642a5b3b7465e75d6c401 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:53:27 +0000 Subject: [PATCH 4/8] minor mistype fixes --- src/front_page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/front_page.ts b/src/front_page.ts index d5a146e8..12769834 100644 --- a/src/front_page.ts +++ b/src/front_page.ts @@ -12,7 +12,7 @@ function osInfo(): string { } function renderLogTail(): string { - if (process.env.ALB_SUPRESS_FRONPAGE_LOG === "1") { + if (process.env.ALB_SUPPRESS_FRONPAGE_LOG === "1") { return ""; } else { const info = getLogTail(); From bc91e5841dc9c3d0c3ed9bcc5f8bb71370987237 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:53:30 +0000 Subject: [PATCH 5/8] docs --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 91e3e8c1..9e29adf7 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,14 @@ your can change the port adding `-e "port=xxx"` param See the content of `docker` directory. There are Dockerfile and docker-compose template. E.g. run `docker build -f docker/Dockerfile -t abaplint-backend .` to build your image from scratch. -TODO: https docker compose, logging advices +*TODO: https docker compose, logging advices* + +### Env variables + +The package respects `.env` file (must not be committed to the repo though!). Here are the available variables: + +- PORT - port to listen at +- ALB_SUPPRESS_FRONPAGE_LOG - disable frontpage log: set `1` to disable ## Development @@ -50,3 +57,5 @@ Useful scripts - docker - `bin/docker-build.sh` - build docker container from command line (supposes bash environment) - `bin/docker-run.sh` - run the built above container + +See also: [docker dev notes](./docker/dev-notes.md) From 0784b1e550842b34a490520a3ab73fd67e5e7c14 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:56:59 +0000 Subject: [PATCH 6/8] test for log tail --- src/lib/log-tail.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/lib/log-tail.test.ts diff --git a/src/lib/log-tail.test.ts b/src/lib/log-tail.test.ts new file mode 100644 index 00000000..80884f40 --- /dev/null +++ b/src/lib/log-tail.test.ts @@ -0,0 +1,10 @@ +import { addInfo, getLogTail } from "./log-tail"; + +test("should add", () => { + addInfo("hello"); + addInfo("world"); + expect(getLogTail()).toEqual([ + "hello", + "world", + ]); +}); From 10ab0568915227991a7dc0a56b19c8ea0c099db3 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:57:04 +0000 Subject: [PATCH 7/8] delete dummy test --- test/dummy.test.ts | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 test/dummy.test.ts diff --git a/test/dummy.test.ts b/test/dummy.test.ts deleted file mode 100644 index b032af5a..00000000 --- a/test/dummy.test.ts +++ /dev/null @@ -1,3 +0,0 @@ -test("should run with jest", () => { - expect(true).toBeTruthy(); -}); \ No newline at end of file From e0b2ad8908893e03cb7db84dface7874c2026bb9 Mon Sep 17 00:00:00 2001 From: Alexander Tsybulsky Date: Sat, 18 Apr 2020 08:59:03 +0000 Subject: [PATCH 8/8] remove duplicate smoke test --- src/app.smoke.test.ts | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/app.smoke.test.ts diff --git a/src/app.smoke.test.ts b/src/app.smoke.test.ts deleted file mode 100644 index bf52f886..00000000 --- a/src/app.smoke.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import app from "./app"; -import * as request from "supertest"; - -test("smoke test: ping", async () => { - const res = await request(app).post("/api/v1/ping"); - expect(res.status).toBe(200); - expect(res.body).toEqual({ success: true, payload: "abap is forevah!" }); -}); - -test("smoke test: 404", async () => { - const res = await request(app).get("/api/v1/zzz"); - expect(res.status).toBe(404); - expect(res.body).toEqual({ success: false, error:{ message: "Wrong API call" }}); -});