diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2017-11-13 19:58:29 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2017-11-13 19:58:29 +0900 |
| commit | 0a994e5b9885265873e02b3b3ab9add7ec7e7e6b (patch) | |
| tree | 3945fc92b149c00cfd103792a50811ade2bc9eae /src | |
| parent | なんかもうめっちゃ変えた (diff) | |
| download | sharkey-0a994e5b9885265873e02b3b3ab9add7ec7e7e6b.tar.gz sharkey-0a994e5b9885265873e02b3b3ab9add7ec7e7e6b.tar.bz2 sharkey-0a994e5b9885265873e02b3b3ab9add7ec7e7e6b.zip | |
Add access log widget
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/stream/requests.ts | 19 | ||||
| -rw-r--r-- | src/api/streaming.ts | 6 | ||||
| -rw-r--r-- | src/log-request.ts | 21 | ||||
| -rw-r--r-- | src/server.ts | 6 | ||||
| -rw-r--r-- | src/web/app/common/mixins/index.ts | 2 | ||||
| -rw-r--r-- | src/web/app/common/scripts/requests-stream-manager.ts | 12 | ||||
| -rw-r--r-- | src/web/app/common/scripts/requests-stream.ts | 14 | ||||
| -rw-r--r-- | src/web/app/desktop/tags/home-widgets/access-log.tag | 93 | ||||
| -rw-r--r-- | src/web/app/desktop/tags/home.tag | 1 | ||||
| -rw-r--r-- | src/web/app/desktop/tags/index.ts | 1 |
10 files changed, 175 insertions, 0 deletions
diff --git a/src/api/stream/requests.ts b/src/api/stream/requests.ts new file mode 100644 index 0000000000..2c36e58b6e --- /dev/null +++ b/src/api/stream/requests.ts @@ -0,0 +1,19 @@ +import * as websocket from 'websocket'; +import Xev from 'xev'; + +const ev = new Xev(); + +export default function homeStream(request: websocket.request, connection: websocket.connection): void { + const onRequest = request => { + connection.send(JSON.stringify({ + type: 'request', + body: request + })); + }; + + ev.addListener('request', onRequest); + + connection.on('close', () => { + ev.removeListener('request', onRequest); + }); +} diff --git a/src/api/streaming.ts b/src/api/streaming.ts index 0e512fb210..6caf7db3e8 100644 --- a/src/api/streaming.ts +++ b/src/api/streaming.ts @@ -9,6 +9,7 @@ import isNativeToken from './common/is-native-token'; import homeStream from './stream/home'; import messagingStream from './stream/messaging'; import serverStream from './stream/server'; +import requestsStream from './stream/requests'; import channelStream from './stream/channel'; module.exports = (server: http.Server) => { @@ -27,6 +28,11 @@ module.exports = (server: http.Server) => { return; } + if (request.resourceURL.pathname === '/requests') { + requestsStream(request, connection); + return; + } + // Connect to Redis const subscriber = redis.createClient( config.redis.port, config.redis.host); diff --git a/src/log-request.ts b/src/log-request.ts new file mode 100644 index 0000000000..e431aa271d --- /dev/null +++ b/src/log-request.ts @@ -0,0 +1,21 @@ +import * as crypto from 'crypto'; +import * as express from 'express'; +import * as proxyAddr from 'proxy-addr'; +import Xev from 'xev'; + +const ev = new Xev(); + +export default function(req: express.Request) { + const ip = proxyAddr(req, () => true); + + const md5 = crypto.createHash('md5'); + md5.update(ip); + const hashedIp = md5.digest('hex').substr(0, 3); + + ev.emit('request', { + ip: hashedIp, + method: req.method, + hostname: req.hostname, + path: req.originalUrl + }); +} diff --git a/src/server.ts b/src/server.ts index 3e9bd44eef..9cf44eb0d0 100644 --- a/src/server.ts +++ b/src/server.ts @@ -11,6 +11,7 @@ import * as morgan from 'morgan'; import Accesses from 'accesses'; import vhost = require('vhost'); +import log from './log-request'; import config from './conf'; /** @@ -35,6 +36,11 @@ app.use(morgan(process.env.NODE_ENV == 'production' ? 'combined' : 'dev', { stream: config.accesslog ? fs.createWriteStream(config.accesslog) : null })); +app.use((req, res, next) => { + log(req); + next(); +}); + // Drop request when without 'Host' header app.use((req, res, next) => { if (!req.headers['host']) { diff --git a/src/web/app/common/mixins/index.ts b/src/web/app/common/mixins/index.ts index 45427fb9d3..a11bfa7b64 100644 --- a/src/web/app/common/mixins/index.ts +++ b/src/web/app/common/mixins/index.ts @@ -3,6 +3,7 @@ import * as riot from 'riot'; import activateMe from './i'; import activateApi from './api'; import ServerStreamManager from '../scripts/server-stream-manager'; +import RequestsStreamManager from '../scripts/requests-stream-manager'; export default (me, stream) => { activateMe(me); @@ -11,4 +12,5 @@ export default (me, stream) => { (riot as any).mixin('stream', { stream }); (riot as any).mixin('server-stream', { serverStream: new ServerStreamManager() }); + (riot as any).mixin('requests-stream', { requestsStream: new RequestsStreamManager() }); }; diff --git a/src/web/app/common/scripts/requests-stream-manager.ts b/src/web/app/common/scripts/requests-stream-manager.ts new file mode 100644 index 0000000000..44db913e78 --- /dev/null +++ b/src/web/app/common/scripts/requests-stream-manager.ts @@ -0,0 +1,12 @@ +import StreamManager from './stream-manager'; +import Connection from './requests-stream'; + +export default class RequestsStreamManager extends StreamManager<Connection> { + public getConnection() { + if (this.connection == null) { + this.connection = new Connection(); + } + + return this.connection; + } +} diff --git a/src/web/app/common/scripts/requests-stream.ts b/src/web/app/common/scripts/requests-stream.ts new file mode 100644 index 0000000000..325224587a --- /dev/null +++ b/src/web/app/common/scripts/requests-stream.ts @@ -0,0 +1,14 @@ +'use strict'; + +import Stream from './stream'; + +/** + * Requests stream connection + */ +class Connection extends Stream { + constructor() { + super('requests'); + } +} + +export default Connection; diff --git a/src/web/app/desktop/tags/home-widgets/access-log.tag b/src/web/app/desktop/tags/home-widgets/access-log.tag new file mode 100644 index 0000000000..a148577563 --- /dev/null +++ b/src/web/app/desktop/tags/home-widgets/access-log.tag @@ -0,0 +1,93 @@ +<mk-access-log-home-widget> + <virtual if={ data.design == 0 }> + <p class="title"><i class="fa fa-server"></i>%i18n:desktop.tags.mk-access-log-home-widget.title%</p> + </virtual> + <div ref="log"> + <p each={ requests }> + <span class="ip" style="color:{ fg }; background:{ bg }">{ ip }</span> + <span>{ method }</span> + <span>{ path }</span> + </p> + </div> + <style> + :scope + display block + overflow hidden + background #fff + + > .title + z-index 1 + margin 0 + padding 0 16px + line-height 42px + font-size 0.9em + font-weight bold + color #888 + box-shadow 0 1px rgba(0, 0, 0, 0.07) + + > i + margin-right 4px + + > div + max-height 250px + overflow auto + + > p + margin 0 + padding 8px + font-size 0.8em + color #555 + + &:nth-child(odd) + background rgba(0, 0, 0, 0.025) + + > .ip + margin-right 4px + + </style> + <script> + import seedrandom from 'seedrandom'; + + this.data = { + design: 0 + }; + + this.mixin('widget'); + + this.mixin('requests-stream'); + this.connection = this.requestsStream.getConnection(); + this.connectionId = this.requestsStream.use(); + + this.requests = []; + + this.on('mount', () => { + this.connection.on('request', this.onRequest); + }); + + this.on('unmount', () => { + this.connection.off('request', this.onRequest); + this.requestsStream.dispose(this.connectionId); + }); + + this.onRequest = request => { + const random = seedrandom(request.ip); + const r = Math.floor(random() * 255); + const g = Math.floor(random() * 255); + const b = Math.floor(random() * 255); + const luma = (0.2126 * r) + (0.7152 * g) + (0.0722 * b); // SMPTE C, Rec. 709 weightings + request.bg = `rgb(${r}, ${g}, ${b})`; + request.fg = luma >= 165 ? '#000' : '#fff'; + + this.requests.push(request); + if (this.requests.length > 30) this.requests.shift(); + this.update(); + + this.refs.log.scrollTop = this.refs.log.scrollHeight; + }; + + this.func = () => { + if (++this.data.design == 2) this.data.design = 0; + this.save(); + }; + </script> +</mk-access-log-home-widget> diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag index fd286851d9..88d06d2baa 100644 --- a/src/web/app/desktop/tags/home.tag +++ b/src/web/app/desktop/tags/home.tag @@ -20,6 +20,7 @@ <option value="recommended-polls">投票</option> <option value="post-form">投稿フォーム</option> <option value="channel">チャンネル</option> + <option value="access-log">アクセスログ</option> <option value="server">サーバー情報</option> <option value="donation">寄付のお願い</option> <option value="nav">ナビゲーション</option> diff --git a/src/web/app/desktop/tags/index.ts b/src/web/app/desktop/tags/index.ts index 15677471c3..8b5a52d670 100644 --- a/src/web/app/desktop/tags/index.ts +++ b/src/web/app/desktop/tags/index.ts @@ -43,6 +43,7 @@ require('./home-widgets/slideshow.tag'); require('./home-widgets/channel.tag'); require('./home-widgets/timemachine.tag'); require('./home-widgets/post-form.tag'); +require('./home-widgets/access-log.tag'); require('./timeline.tag'); require('./messaging/window.tag'); require('./messaging/room-window.tag'); |