Skip to content

Commit 3d00937

Browse files
authored
Merge pull request #334 from hwong0305/deleteLogs
Fix(Issue #333) - Add functionality to clear Logs
2 parents be4b0be + a69f1e0 commit 3d00937

File tree

3 files changed

+86
-23
lines changed

3 files changed

+86
-23
lines changed

src/api/logs.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,26 @@ logsRouter.get('/out/:domain', (req, res) => {
4040
}
4141
})
4242

43+
logsRouter.delete('/:domain', (req, res) => {
44+
const { domain } = req.params
45+
46+
if (isProduction())
47+
fs.writeFile(
48+
`/home/myproxy/.pm2/logs/${domain}-out.log`,
49+
'Log cleared\n',
50+
err => {
51+
if (err) console.log('Error deleting output log')
52+
}
53+
)
54+
fs.writeFile(
55+
`/home/myproxy/.pm2/logs/${domain}-err.log`,
56+
'Log cleared\n',
57+
err => {
58+
if (err) console.log('Error deleting error log')
59+
}
60+
)
61+
62+
res.send('LOGS DELETED')
63+
})
64+
4365
export default logsRouter

src/public/client.ts

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,24 @@ class MappingItem {
4141
const mappingElement = document.createElement('li')
4242
let iconClass
4343
let iconColor
44-
// LogClass is used to hide the button to download logs when
45-
// pm2 is not managing the apps. Since pm2 is not managing the apps,
46-
// the logs will not be located at the same location
44+
// The variables below are to hide log related icons when pm2 is not
45+
// being used to monitor the apps. These apps will not have status since
46+
// they are not managed by pm2.
47+
let settingClass
4748
let logClass
4849
if (data.status === 'online') {
4950
iconClass = 'fa fa-circle mr-1 mt-1'
5051
iconColor = 'rgba(50,255,50,0.5)'
5152
logClass = 'fa fa-file-text-o ml-1 mt-1'
53+
settingClass = 'ml-1 fa fa-cog'
5254
} else if (data.status === 'not started') {
5355
iconClass = ''
5456
iconColor = 'transparent'
5557
} else {
5658
iconClass = 'fa fa-circle mr-1 mt-1'
5759
iconColor = 'rgba(255, 50, 50, 0.5)'
5860
logClass = 'fa fa-file-text-o ml-1 mt-1'
61+
settingClass = 'ml-1 fa fa-cog'
5962
}
6063
mappingElement.classList.add(
6164
'list-group-item',
@@ -64,38 +67,59 @@ class MappingItem {
6467
)
6568
domainList.appendChild(mappingElement)
6669
mappingElement.innerHTML = `
67-
<div style='width: 100%'>
68-
<div style='display: flex'>
70+
<div style="width: 100%">
71+
<div style="display: flex">
6972
<i class="${iconClass}" style="font-size: 15px; color: ${iconColor}">
7073
</i>
71-
<a class="font-weight-bold"
72-
href="https://${data.fullDomain}">
74+
<a class="font-weight-bold" href="https://${data.fullDomain}">
7375
${data.fullDomain}
7476
</a>
7577
<small class="form-text text-muted ml-1">
7678
PORT: ${data.port}
7779
</small>
78-
<a class="${logClass}"
80+
<a
81+
class="${logClass}"
7982
style="font-size: 15px; color: rgba(255,50,50,0.5)"
80-
href="/api/logs/err/${data.fullDomain}">
83+
href="/api/logs/err/${data.fullDomain}"
84+
>
8185
</a>
82-
<a class="${logClass}"
83-
style="font-size: 15px; color: rgba(40,167,70,0.5)"
84-
href="/api/logs/out/${data.fullDomain}">
86+
<a
87+
class="${logClass}"
88+
style="font-size: 15px; color: rgba(40,167,70,0.5)"
89+
href="/api/logs/out/${data.fullDomain}"
90+
>
8591
</a>
92+
<div class="dropright">
93+
<a href="#" role="button" data-toggle="dropdown" class="btn-link">
94+
<span class="${settingClass}" style="font-size: 15px"> </span>
95+
</a>
96+
<div class="dropdown-menu">
97+
<button
98+
type="button"
99+
class="btn btn-link deleteLogButton"
100+
style="color: rgba(255,50,50,1)"
101+
>
102+
Clear Logs
103+
</button>
104+
</div>
105+
</div>
86106
</div>
87107
<small class="form-text text-muted" style="display: inline-block;">
88108
${data.gitLink}
89109
</small>
90110
</div>
91-
<a href="/api/mappings/download/?fullDomain=${data.fullDomain}"
92-
target="_blank" class="btn btn-sm btn-outline-success mr-3">
93-
Download<i class="fa fa-download"></i>
111+
<a
112+
href="/api/mappings/download/?fullDomain=${data.fullDomain}"
113+
target="_blank"
114+
class="btn btn-sm btn-outline-success mr-3"
115+
>
116+
Download<i class="fa fa-download"></i>
94117
</a>
95118
<button
96119
class="btn btn-sm btn-outline-danger mr-3 deleteButton"
97-
type="button">
98-
Delete
120+
type="button"
121+
>
122+
Delete
99123
</button>
100124
`
101125

@@ -113,6 +137,18 @@ class MappingItem {
113137
})
114138
}
115139
}
140+
const clearLogButton = helper.getElement('.deleteLogButton', mappingElement)
141+
clearLogButton.onclick = (): void => {
142+
if (
143+
confirm(`Are you sure you want to clear ${data.fullDomain}'s logs?`)
144+
) {
145+
fetch(`/api/logs/${data.fullDomain}`, {
146+
method: 'DELETE'
147+
}).then(() => {
148+
window.location.reload()
149+
})
150+
}
151+
}
116152
}
117153
}
118154

src/tests/integration/log.test.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { startAppServer } from '../../server/server'
2+
import uuidv4 from 'uuid/v4'
23
import { logAdapter } from '../helpers/logAdapter'
34

45
const TEST_PORT = process.env.PORT || 50608
@@ -16,16 +17,20 @@ describe('/api/logs', () => {
1617
})
1718

1819
it('checks that output logs endpoint exists', async () => {
19-
const subDomain = 'Cloud'
20-
const domain = 'Walker'
21-
const logResponse = await logAdapter(`/out/${subDomain}.${domain}`, 'GET')
20+
const fullDomain = 'Cloud.Walker.com'
21+
const logResponse = await logAdapter(`/out/${fullDomain}`, 'GET')
2222
expect(logResponse.status).toEqual(200)
2323
})
2424

2525
it('checks that error logs endpoint exists', async () => {
26-
const subDomain = 'Luke'
27-
const domain = 'Walker'
28-
const logResponse = await logAdapter(`/err/${subDomain}.${domain}`, 'GET')
26+
const fullDomain = 'Luke.Walker.com'
27+
const logResponse = await logAdapter(`/err/${fullDomain}`, 'GET')
28+
expect(logResponse.status).toEqual(200)
29+
})
30+
31+
it('checks the delete endpoint exists', async () => {
32+
const fullDomain = `${uuidv4()}.walker.com`
33+
const logResponse = await logAdapter(`/${fullDomain}`, 'DELETE')
2934
expect(logResponse.status).toEqual(200)
3035
})
3136
})

0 commit comments

Comments
 (0)