Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(metrics): Add machine-readable logs to measure performance #55

Merged
merged 7 commits into from
Sep 24, 2020
Merged
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
4 changes: 4 additions & 0 deletions .example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PORT=8080
TWITTER_CONSUMER_KEY=XXXXX
TWITTER_CONSUMER_SECRET=XXXXX
NODE_ENV=local
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ addons:
if: branch IN (master, develop)
script:
- npm test
after_success:
- npm run upload-coverage
before_install:
- openssl aes-256-cbc -K $encrypted_cfeaf5955b9b_key -iv $encrypted_cfeaf5955b9b_iv
Expand Down
2 changes: 1 addition & 1 deletion README-EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![](https://img.shields.io/docker/automated/german1608/t-creo?style=flat-square) ![](https://img.shields.io/travis/t-creo/back-end/develop?style=flat-square) ![npm type definitions](https://img.shields.io/npm/types/typescript?style=flat-square) [![Coverage Status](https://coveralls.io/repos/github/t-creo/back-end/badge.svg?branch=develop)](https://coveralls.io/github/t-creo/back-end?branch=develop)

Backend for the World White Web Application. Miniproject of software development
Backend for the T-CREo Application. Miniproject of software development
of Simon Bolivar University.

## Members
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![](https://img.shields.io/docker/automated/german1608/t-creo?style=flat-square) ![](https://img.shields.io/travis/t-creo/back-end/develop?style=flat-square) ![npm type definitions](https://img.shields.io/npm/types/typescript?style=flat-square) [![Coverage Status](https://coveralls.io/repos/github/t-creo/back-end/badge.svg?branch=develop)](https://coveralls.io/github/t-creo/back-end?branch=develop)

Backend para la aplicación World White Web. MiniProyecto de Desarrollo de Software para la USBve.
Backend para la aplicación T-CREo. MiniProyecto de Desarrollo de Software para la USBve.

_If you want to see the english version, see [here](./README-EN.md)_

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "t-creo-back-end",
"version": "1.0.0",
"description": "Backend para la aplicación World White Web",
"description": "Backend para la aplicación T-CREo",
"main": "server.js",
"scripts": {
"start": "nodemon --watch src --exec ts-node src/server.ts",
Expand Down
44 changes: 44 additions & 0 deletions scripts/analyzeTimes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const fs = require('fs')

const LOGS_PATH = process.argv[2]

fs.readFile(LOGS_PATH, 'utf8', (err, contents) => {
if (err) throw err;
const objects = contents.split('\n')
.filter(v => {
try {
JSON.parse(v)
return true
} catch (e) {
return false
}
})
.map(JSON.parse)
.filter(v => typeof v == 'object' && v.metric && v.time)

const textCredibilities = objects
.filter(v => v.metric === 'TEXT_CREDIBILITY')
.map(v => v.time)
console.log(textCredibilities)
console.log({
avg: avg(textCredibilities),
min: min(textCredibilities),
max: max(textCredibilities)
})
})

function sum(v) {
return v.reduce((prev, curr) => prev + curr, 0)
}

function avg(v) {
return sum(v) / v.length
}

function min(v) {
return v.reduce((prev, curr) => prev < curr ? prev : curr, v[0])
}

function max(v) {
return v.reduce((prev, curr) => prev < curr ? curr : prev, v[0])
}
7 changes: 7 additions & 0 deletions scripts/analyze_logs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

t=$(mktemp)
echo "Getting logs from container $1 and saving to $t"
docker logs $1 > $t
node analyzeTimes.js $t
rm $t
10 changes: 10 additions & 0 deletions scripts/deploy_docker_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Easy way to pull & run our docker image

DOCKER_IMAGE=german1608/t-creo:latest
DOCKER_CONTAINER=t-creo

docker container rm -f $DOCKER_CONTAINER
docker image rm -f $DOCKER_IMAGE
docker pull $DOCKER_IMAGE
docker run --name $DOCKER_CONTAINER -d --env-file .env -p 3000:3000 $DOCKER_IMAGE
6 changes: 3 additions & 3 deletions src/calculator/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import { asyncWrap } from '../utils'

const calculatorRoutes = express.Router()

calculatorRoutes.get('/plain-text', validate('calculateTextCredibility'), asyncWrap(async function(req, res) {
calculatorRoutes.get('/plain-text', validate('calculateTextCredibility'), function(req, res) {
const errors = validationResult(req)
if (!errors.isEmpty()) {
errorMapper(errors.array())
}
res.json(await calculateTextCredibility({
res.json(calculateTextCredibility({
text: req.query.text,
lang: req.query.lang
}, {
weightBadWords: +req.query.weightBadWords,
weightMisspelling: +req.query.weightMisspelling,
weightSpam: +req.query.weightSpam
}))
}))
})

calculatorRoutes.get('/twitter/user/:id', validate('twitterUserCredibility'), asyncWrap(async function(req, res) {
const errors = validationResult(req)
Expand Down
22 changes: 14 additions & 8 deletions src/calculator/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import NSpell from 'nspell'
import wash from 'washyourmouthoutwithsoap'
import SimpleSpamFilter, { SimpleSpamFilterParams } from './spam-filter'
import fs from 'fs'
import { performance } from 'perf_hooks'
import path from 'path'
import emojiStrip from 'emoji-strip'

Expand Down Expand Up @@ -122,7 +123,7 @@ function spamCriteria(text: Text) : number {
: 100
}

async function missSpellingCriteria(text: Text) : Promise<number> {
function missSpellingCriteria(text: Text) : number {
const cleanedText = cleanText(text.text)
const wordsInText = getCleanedWords(cleanedText)
const spellingChecker = spellingCheckers[text.lang]
Expand All @@ -135,13 +136,18 @@ async function missSpellingCriteria(text: Text) : Promise<number> {
return 100 - (100 * numOfMissSpells / wordsInText.length)
}

async function calculateTextCredibility(text: Text, params: TextCredibilityWeights) : Promise<Credibility> {
function calculateTextCredibility(text: Text, params: TextCredibilityWeights) : Credibility {
const start = performance.now()
const badWordsCalculation = params.weightBadWords * badWordsCriteria(text.text)
const spamCalculation = params.weightSpam * spamCriteria(text)
const missSpellingCalculation = params.weightMisspelling * (await missSpellingCriteria(text))
return {
credibility: badWordsCalculation + spamCalculation + missSpellingCalculation
}
const missSpellingCalculation = params.weightMisspelling * missSpellingCriteria(text)
const credibility = badWordsCalculation + spamCalculation + missSpellingCalculation
const end = performance.now()
console.log(JSON.stringify({
time: end - start,
metric: 'TEXT_CREDIBILITY'
}))
return { credibility }
}

async function getUserInfo(userId: string) : Promise<TwitterUser> {
Expand Down Expand Up @@ -211,7 +217,7 @@ async function calculateTweetCredibility(tweetId: string,
const tweet: Tweet = await getTweetInfo(tweetId)
const user: TwitterUser = tweet.user
const userCredibility: number = calculateUserCredibility(user) * params.weightUser
const textCredibility: number = (await calculateTextCredibility(tweet.text, params)).credibility * params.weightText
const textCredibility: number = calculateTextCredibility(tweet.text, params).credibility * params.weightText
const socialCredibility: number = calculateSocialCredibility(user, maxFollowers) * params.weightSocial
return {
credibility: userCredibility + textCredibility + socialCredibility
Expand Down Expand Up @@ -263,7 +269,7 @@ async function socialCredibility(userID: string, maxFollowers: number) {

async function scrapedtweetCredibility(tweetText: Text, tweetCredibilityWeights: TweetCredibilityWeights, twitterUser: TwitterUser, maxFollowers: number){
const userCredibility: number = calculateUserCredibility(twitterUser) * tweetCredibilityWeights.weightUser
const textCredibility: number = (await calculateTextCredibility(tweetText, tweetCredibilityWeights)).credibility * tweetCredibilityWeights.weightText
const textCredibility: number = calculateTextCredibility(tweetText, tweetCredibilityWeights).credibility * tweetCredibilityWeights.weightText
const socialCredibility: number = calculateSocialCredibility(twitterUser, maxFollowers) * tweetCredibilityWeights.weightSocial
return {
credibility: userCredibility + textCredibility + socialCredibility
Expand Down