File size: 2,622 Bytes
a30e098
 
 
061bbff
a30e098
 
 
 
 
061bbff
 
 
 
 
 
288a9c5
061bbff
 
 
 
 
 
 
 
7a0083a
 
 
 
 
 
061bbff
 
7a0083a
 
 
 
 
 
 
 
 
 
 
 
061bbff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d69fbe4
 
 
061bbff
 
 
 
 
 
 
 
 
 
 
df25c1b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
{ cpus, loadavg, networkInterfaces, platform, release, tmpdir, type, uptime: osUptime, userInfo } := require 'node:os'
{ env, memoryUsage, report, uptime: procUptime, versions } := require 'node:process'
{ format } := require 'node:util'

bytes := require 'bytes'
express := require 'express'
morgan := require 'morgan'
{ default: prettyMs } := require 'pretty-ms'
serveIndex := require 'serve-index'

limitSize := '69mb'
PORT := env.SERVER_PORT or env.PORT or 7860
timeZone := env.TZ or 'Asia/Jakarta'
tmpDir := tmpdir()

formatBytes := (val: number) -> bytes val, unitSeparator: ' '
isNumber := (val: unknown): val is number -> typeof val is 'number'

snakeRgx := /_(\w)/g
snakeToCamel := (str: string) -> str.replace snakeRgx, (_, g) -> g.toUpperCase()

logger := (...args: any[]) ->
  console.log new Date().toLocaleTimeString('fr', { timeZone }), ...args

prettifyMetrics := (obj: any, condition?: (k: string, v: any) -> boolean) ->
  condition ?= (_, v) -> isNumber v
  jsonStr := JSON.stringify obj, (key, val) ->
    if condition key, val then formatBytes val else val
  cleanJson := jsonStr.replace /_(\w)/g, (_, g) -> g.toUpperCase()
  JSON.parse cleanJson

getServerStats := ->
  stats := {}
  stats.uptime = prettyMs procUptime() * 1e3
  stats.osUptime = prettyMs osUptime() * 1e3

  if rep := report?.getReport?()
    Object.assign stats,
      getReport: rep.header
      javascriptHeap: prettifyMetrics rep.javascriptHeap, (k, v) ->
        isNumber v and not /(ContextCount|Garbage)/i.test k
      resourceUsage: prettifyMetrics rep.resourceUsage, (k, v) ->
        isNumber v and not /(Percent|IO|reads|write)/i.test k
      uvthreadResourceUsage: rep.uvthreadResourceUsage

  stats.memoryUsage = prettifyMetrics memoryUsage()
  stats

app := express()
  |> .enable 'trust proxy'
  |> .set 'etag', false
  |> .set 'json spaces', 2
  |> .use express.json limit: limitSize
  |> .use express.urlencoded extended: true, limit: limitSize
  |> .use morgan 'dev'
  |> .use '/tmp', express.static(tmpDir), serveIndex tmpDir, hidden: true, icons: true

app.all '/', (_, res) ->
  res.set 'Cache-Control', 'no-store, no-cache, must-revalidate'
  res.json getServerStats()

app.get '/sys/cpu', (_, res) ->
  res.json
    loadAvg: loadavg()
    cpus: cpus().map ({ model, speed }) -> { model, speed }

app.get '/sys/net', (_, res) ->
  res.json networkInterfaces()

app.get '/sys/node', (_, res) ->
  res.json versions

app.get '/sys/os', (_, res) ->
  res.json
    platform: platform()
    release: release()
    type: type()
    user: userInfo().username

app.listen PORT, ->
  logger 'Server running on port', PORT