A simple web based client to view and filter logs. This project was originally implemented using server side view rendering and hacked together XHR requests to update the front-end in real time. Currently transitioning to a React based front-end with a RESTful API.
TODO
- Implement config interface
- Implement logfile directory interface
- Integrate front-end with API
- Rethink route handling on the front-end (React router)
- Improve front-end request handling (possible Redux longterm)
- Write front-end tests and increase server test coverage
- Include more API call examples in readme
- Server side config validation (probably JSON schema)
Running This Project
- Running the dev environment:
npm run dev
- Running the dev environment in debug mode:
npm run dev-debug
- Running the backend with an optimized front-end build :
npm start
- Building the front-end:
npm run build
- Running tests (and standard linter):
npm test
- Running the standard linter (included in
npm test
):npm run lint
Note: Running or building the client lints with babel-eslint
Client Side
Implemented in React and bundled with Webpack.
Sketch Mockups (work in progress)
Phone Viewport
Tablet Viewport
Desktop Viewport
Prototype Demo
This prototype is implemented using Express/Jade view rendering and hacked together front end code (but it looks kinda pretty).
Watch here
File DemoWatch here
Live DemoServer Side
Routes
POST
/api/config
Modifies the config. Only the supplied keys are applied, other keys are left as is.
Example requests body
"datetimePattern": "\\[(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z)\\]" "levelPattern": "\\[([\\w\\s]+|\\w+)\\]:\\s" "timeFormatter": "h:MM:ss"
Example Response
"success": true "msg": "Config set: true" "data": "datetimePattern": "\\[(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z)\\]" "levelPattern": "\\[([\\w\\s]+|\\w+)\\]:\\s" "timeFormatter": "h:MM:ss" "inputTimezone": 0 "outputTimezone": 8 "directories": "path": "/var/log/somelogs" "name": "Some Wonderful Logs" "key": 0 "active": false "path": "/var/log/someotherlogs" "name": "Some Other Wonderful Logs" "key": 1 "active": true
GET
/api/config
Example Response
"success": true "msg": "Config read" "data": "datetimePattern": "\\[(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z)\\]" "levelPattern": "\\[([\\w\\s]+|\\w+)\\]:\\s" "timeFormatter": "h:MM:ss" "inputTimezone": 0 "outputTimezone": 8 "directories": "path": "/var/log/somelogs" "name": "Some Wonderful Logs" "key": 0 "active": false "path": "/var/log/someotherlogs" "name": "Some Other Wonderful Logs" "key": 1 "active": true
GET
/api/file
Example Request
GET
http://localhost:4000/api/file?key=0&startdt=1489387840000&enddt=1490333975974&level=4&pagesize=20&pagenum=1
Param | Type | Description |
---|---|---|
key | integer | Key for a given logfile retreieved from GET /api/directory |
pagenum | integer | Current page number |
pagesize | integer | Number of log entries per page |
startdt | datetime string | Starting datetime |
enddt | datetime string | Ending datetime |
level | One of Level Enum | Log severity level defined below |
Level Enum
Level | Value |
---|---|
Error | 0 |
Warning | 1 |
Info | 2 |
Verbose | 3 |
Debug | 4 |
Example Response
"success": true "msg": "Queried /Users/nick/Documents/slask/src/server/test/fixtures/testlog.log" "data": "text": "You must be pretty desperate if you're looking at the logs" "level": 2 "levelStr": "info" "datetime": 1489387840000 "datetimeStr": "6:50:40" "text": "Hello world" "level": 0 "levelStr": "error" "datetime": 1489387841000 "datetimeStr": "6:50:41" "text": "Lovely weather we're having" "level": 1 "levelStr": "warn" "datetime": 1489387841000 "datetimeStr": "6:50:41" "text": "That's all for now folks" "level": 4 "levelStr": "debug" "datetime": 1489387841000 "datetimeStr": "6:50:41" "text": "You must be pretty desperate if you're looking at the logs" "level": 4 "levelStr": "debug" "datetime": 1489387840000 "datetimeStr": "6:50:40"
GET
/api/directories
Lists directories added by PUT
/api/directories
Example Response
"success": true "msg": "Successfully listed directories" "data": "path": "/var/log/somelogs" "name": "Some Wonderful Logs" "key": 0 "active": false "path": "/var/log/someotherlogs" "name": "Some Other Wonderful Logs" "key": 1 "active": true
PUT
/api/directories
Adds a new directory to the list retrieved from GET
/api/directories
Example Request
"path": "/var/log/somelogs" "name": "Some Wonderful Logs"
Example Response
"success": true "msg": "Successfully listed directories" "data": "path": "/var/log/somelogs" "name": "Some Wonderful Logs" "key": 0 "active": false "path": "/var/log/someotherlogs" "name": "Some Other Wonderful Logs" "key": 1 "active": true
POST
/api/directories
Modify directory to the list retrieved from GET
/api/directories
Example Request
"path": "/var/log/somelogs" "name": "Some Wonderful New Name Logs" "key": 0
Example Response
"success": true "msg": "Successfully modified directory" "data": "path": "/var/log/somelogs" "name": "Some Wonderful Logs" "key": 0 "active": false "path": "/var/log/someotherlogs" "name": "Some Other Wonderful Logs" "key": 1 "active": true
GET
/api/directory
Gets the directory listing for the directory set in POST
/api/directory
Example Response
"success": true "msg": "Successfully retrieved directory listing" "data": "name": "log0.log" "key": 0 "name": "log1.log" "key": 1
POST
/api/directory
Sets the active directory to be used for GET
/api/file
. Please note this directory will be parsed ahead of time so requests on GET
/api/file
are very quick.
Example Request
"key": 0
Example Response
"success": true "msg": "Successfully set active directory" "data": "key": 0 }