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

[DDW-248] Refactor compress/download logs handling #995

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ffd61bd
[DDW-248] Refactor compress/download logs handling
thedanheller Jun 26, 2018
3f4af8c
[DDW-248] Saving with the same timestamp
thedanheller Jun 27, 2018
88b9c50
[DDW-248] Removing logs on init
thedanheller Jun 27, 2018
c8f2a81
[DDW-248] Get fresh logs when submitting a support request
thedanheller Jun 29, 2018
15c2a1e
[DDW-248] CHANGELOG
thedanheller Jul 2, 2018
5976494
[DDW-248] UTC timestamp and FLOW
thedanheller Jul 4, 2018
e39f322
[DDW-248] Requesting logs only upon form submition
thedanheller Jul 4, 2018
2d5a251
[DDW-248] Removes useless extra lines
thedanheller Jul 4, 2018
7ab1f8f
[DDW-248] Renaming getFreshLogs to avoid confusion
thedanheller Jul 4, 2018
afd1343
Merge branch 'develop' into chore/ddw-248-refactor-compress-download-…
thedanheller Jul 4, 2018
242710e
[DDW-248] Flow errors
thedanheller Jul 4, 2018
81a444d
[DDW-248] lint error
thedanheller Jul 4, 2018
9a3a123
[DDW-248] Adjustments
thedanheller Jul 5, 2018
344d5d5
[DDW-248] linting
thedanheller Jul 5, 2018
37d9bf5
[DDW-248] getting logs on dialog open
thedanheller Jul 6, 2018
0d42e24
[DDW-248] Adjustments
thedanheller Jul 6, 2018
74ada87
Merge branch 'develop' into chore/ddw-248-refactor-compress-download-…
thedanheller Jul 6, 2018
6913da9
Merge branch 'develop' into chore/ddw-248-refactor-compress-download-…
DominikGuzei Jul 10, 2018
a7af4f1
[DDW-248] Code style improvements
nikolaglumac Jul 10, 2018
af76c11
[DDW-248] Code style improvements
nikolaglumac Jul 10, 2018
27fc619
[DDW-248] Code improvements
thedanheller Jul 10, 2018
43a75fc
[DDW-248] lint warning
thedanheller Jul 10, 2018
d68a724
[DDW-248] Code style improvements
nikolaglumac Jul 12, 2018
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Changelog
- Added acceptance tests for node update notification with apply and postpone update scenarios ([PR 977](https://github.com/input-output-hk/daedalus/pull/977))
- Added acceptance tests for maximum wallets limit ([PR 979](https://github.com/input-output-hk/daedalus/pull/979))
- Added acceptance tests for the About dialog ([PR 975](https://github.com/input-output-hk/daedalus/pull/975))
- Improved compress/download logs handling ([PR 995](https://github.com/input-output-hk/daedalus/pull/995))

## 0.10.1
=======
Expand Down
13 changes: 13 additions & 0 deletions source/common/fileName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @flow
import moment from 'moment';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daniloprates please add // @flow to the top of this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔︎


export const generateFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') =>
`${prefix}-${moment.utc().format('YYYY-MM-DDTHHmmss.0SSS')}Z.${fileType}`;

export const isFileNameWithTimestamp = (prefix: string = 'logs', fileType: string = 'zip') => (fileName: string) =>
fileName.match(RegExp(`(${prefix}-)([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}.0[0-9]{3}Z)(.${fileType})`));

export const getPathSlash = (path: string) => ((path.indexOf('/') > -1) ? '/' : '\\');

export const extractFileNameFromPath = (path: string) =>
path.substr(path.lastIndexOf(getPathSlash(path)) + 1);
7 changes: 0 additions & 7 deletions source/common/ipc-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ export const COMPRESS_LOGS = {
ERROR: `${COMPRESS_LOGS_CHANNEL}-error`,
};

const DELETE_COMPRESSED_LOGS_CHANNEL = 'delete-compressed-logs';
export const DELETE_COMPRESSED_LOGS = {
REQUEST: DELETE_COMPRESSED_LOGS_CHANNEL,
SUCCESS: `${DELETE_COMPRESSED_LOGS_CHANNEL}-success`,
ERROR: `${DELETE_COMPRESSED_LOGS_CHANNEL}-error`,
};

const DOWNLOAD_LOGS_CHANNEL = 'download-logs';
export const DOWNLOAD_LOGS = {
REQUEST: DOWNLOAD_LOGS_CHANNEL,
Expand Down
4 changes: 1 addition & 3 deletions source/main/ipc-api/compress-logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import { Logger, stringifyError } from '../../common/logging';
import { COMPRESS_LOGS } from '../../common/ipc-api';

export default () => {
ipcMain.on(COMPRESS_LOGS.REQUEST, (event, logs) => {
ipcMain.on(COMPRESS_LOGS.REQUEST, (event, logs, compressedFileName) => {
const sender = event.sender;
const compressedFileName = 'logs.zip';

const outputPath = path.join(appLogsFolderPath, compressedFileName);
const output = fs.createWriteStream(outputPath);
const archive = archiver('zip', {
Expand Down
19 changes: 0 additions & 19 deletions source/main/ipc-api/delete-compressed-logs.js

This file was deleted.

2 changes: 0 additions & 2 deletions source/main/ipc-api/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @flow
import compressLogsApi from './compress-logs';
import deleteCompressedLogsApi from './delete-compressed-logs';
import downloadLogsApi from './download-logs';
import getLogsApi from './get-logs';
import parseRedemptionCodeApi from './parse-redemption-code-from-pdf';
Expand All @@ -10,7 +9,6 @@ import loadAsset from './load-asset';

export default (params: any) => {
compressLogsApi();
deleteCompressedLogsApi();
downloadLogsApi();
getLogsApi();
parseRedemptionCodeApi();
Expand Down
18 changes: 17 additions & 1 deletion source/main/utils/setupLogging.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import fs from 'fs';
import path from 'path';
import log from 'electron-log';
import moment from 'moment';
import ensureDirectoryExists from './ensureDirectoryExists';
import { pubLogsFolderPath, APP_NAME } from '../config';
import { pubLogsFolderPath, appLogsFolderPath, APP_NAME } from '../config';
import { isFileNameWithTimestamp } from '../../common/fileName';

const isTest = process.env.NODE_ENV === 'test';

Expand All @@ -19,4 +21,18 @@ export const setupLogging = () => {
const formattedDate = moment.utc(msg.date).format('YYYY-MM-DDTHH:mm:ss.0SSS');
return `[${formattedDate}Z] [${msg.level}] ${msg.data}`;
};

// Removes existing compressed logs
fs.readdir(appLogsFolderPath, (err, files) => {
files
.filter(isFileNameWithTimestamp())
.forEach((logFileName) => {
const logFile = path.join(appLogsFolderPath, logFileName);
try {
fs.unlinkSync(logFile);
} catch (error) {
console.error(`Compressed log file "${logFile}" deletion failed: ${error}`);
}
});
});
};
9 changes: 4 additions & 5 deletions source/renderer/app/actions/profile-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import Action from './lib/Action';

export default class ProfileActions {
acceptTermsOfUse: Action<any> = new Action();
compressLogs: Action<{ logs: Object }> = new Action();
getLogs: Action<any> = new Action();
downloadLogs: Action<{ destination: string, fresh?: boolean }> = new Action();
deleteCompressedLogs: Action<any> = new Action();
resetBugReportDialog: Action<any> = new Action();
getLogsAndCompress: Action<any> = new Action();
sendBugReport: Action<{
email: string, subject: string, problem: string, compressedLog: ?string,
email: string, subject: string, problem: string, compressedLogsFile: ?string,
}> = new Action();
resetBugReportDialog: Action<any> = new Action();
downloadLogs: Action<{ fileName: string, destination: string, fresh?: boolean }> = new Action();
updateLocale: Action<{ locale: string }> = new Action();
updateTheme: Action<{ theme: string }> = new Action();
}
6 changes: 3 additions & 3 deletions source/renderer/app/api/ada/sendAdaBugReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ export type SendAdaBugReportRequestParams = {
email: string,
subject: string,
problem: string,
compressedLog: string,
compressedLogsFile: string,
},
application: string,
};

export const sendAdaBugReport = (
{ requestFormData, application }: SendAdaBugReportRequestParams
): Promise<{}> => {
const { email, subject, problem, compressedLog } = requestFormData;
const { email, subject, problem, compressedLogsFile } = requestFormData;
const reportUrl = url.parse(environment.REPORT_URL);

let platform;
Expand Down Expand Up @@ -45,7 +45,7 @@ export const sendAdaBugReport = (
version: environment.version,
build: environment.build,
os: platform,
compressedLog,
compressedLogsFile,
date: moment().format('YYYY-MM-DDTHH:mm:ss'),
magic: 2000000000,
type: {
Expand Down
6 changes: 3 additions & 3 deletions source/renderer/app/api/etc/sendEtcBugReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ export type SendEtcBugReportRequestParams = {
email: string,
subject: string,
problem: string,
compressedLog: string,
compressedLogsFile: string,
},
application: string,
};

export const sendEtcBugReport = (
{ requestFormData, application }: SendEtcBugReportRequestParams
): Promise<{}> => {
const { email, subject, problem, compressedLog } = requestFormData;
const { email, subject, problem, compressedLogsFile } = requestFormData;
const reportUrl = url.parse(environment.REPORT_URL);

let platform;
Expand Down Expand Up @@ -45,7 +45,7 @@ export const sendEtcBugReport = (
version: environment.version,
build: environment.build,
os: platform,
compressedLog,
compressedLogsFile,
date: moment().format('YYYY-MM-DDTHH:mm:ss'),
magic: 2000000000,
type: {
Expand Down
8 changes: 5 additions & 3 deletions source/renderer/app/api/lib/reportRequest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import http from 'http';
import FormData from 'form-data/lib/form_data';
import fs from 'fs';
import { extractFileNameFromPath } from '../../../../common/fileName';

export type RequestOptions = {
hostname: string,
Expand Down Expand Up @@ -38,9 +39,10 @@ function typedHttpRequest<Response>(
formData.append('payload', JSON.stringify(payload));

// prepare file stream (attachment)
if (payload.compressedLog) {
const stream = fs.createReadStream(payload.compressedLog);
formData.append('logs.zip', stream);
if (payload.compressedLogsFile) {
const stream = fs.createReadStream(payload.compressedLogsFile);
const fileName = extractFileNameFromPath(payload.compressedLogsFile);
formData.append(fileName, stream);
}

options.headers = formData.getHeaders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,20 @@ const messages = defineMessages({

type Props = {
logFiles: LogFiles,
compressedLog: ?string,
onCancel: Function,
onSubmit: Function,
onSubmitManually: Function,
onDownload: Function,
onGetLogs: Function,
onCompressLogs: Function,
onDeleteCompressedLogs: Function,
isSubmitting: boolean,
isCompressing: boolean,
onGetLogsAndCompress: Function,
isDownloading?: boolean,
isSubmittingBugReport?: boolean,
error: ?LocalizableError,
};

type State = {
showLogs: boolean,
attachLogs: boolean,
compressedLogsFile: ?string,
};

@observer
Expand All @@ -144,19 +142,23 @@ export default class BugReportDialog extends Component<Props, State> {
};

state = {
showLogs: true,
attachLogs: true,
compressedLogsFile: null,
};

componentWillMount() {
this.props.onGetLogs();
this.props.onDeleteCompressedLogs();
}

componentWillReceiveProps(nextProps: Object) {
const commpressionFilesChanged = this.props.compressedLog !== nextProps.compressedLog;
if (nextProps.compressedLog && commpressionFilesChanged && !nextProps.isDownloading) {
// proceed to submit when ipc rendered successfully return compressed files
this.submit(nextProps.compressedLog);
const compressedLogsFileChanged = (
!this.props.compressedLogsFile &&
!!nextProps.compressedLogsFile
);
const { compressedLogsFile } = this.state;
if (compressedLogsFile) return false;
if (nextProps.compressedLogsFile && compressedLogsFileChanged && !nextProps.isDownloading) {
this.setState({ compressedLogsFile: nextProps.compressedLogsFile }, this.submit);
}
}

Expand Down Expand Up @@ -206,40 +208,36 @@ export default class BugReportDialog extends Component<Props, State> {
},
});

submit = (compressedLog: ?string) => {
submit = () => {
this.form.submit({
onSuccess: (form) => {
const { logFiles } = this.props;
const logsExist = get(logFiles, ['files'], []).length > 0;

const { attachLogs, compressedLogsFile } = this.state;
if (attachLogs && !compressedLogsFile) {
this.props.onGetLogsAndCompress();
return false;
}
const { email, subject, problem } = form.values();
const data = {
email, subject, problem, compressedLog
email, subject, problem, compressedLogsFile
};

if (this.state.showLogs && logsExist && !compressedLog) {
// submit request with commpressed logs files
this.props.onCompressLogs(this.props.logFiles);
} else {
// regular submit
this.props.onSubmit(data);
}
this.props.onSubmit(data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daniloprates we shouldn't send the log files if the user has set the "attach-logs" switch to off state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔︎

},
onError: () => {},
});
};

handleLogsSwitchToggle = (value: boolean) => {
this.setState({ showLogs: value });
this.setState({ attachLogs: value });
};

onClose = () => !this.props.isSubmittingBugReport && this.props.onCancel();

render() {
const { intl } = this.context;
const { showLogs } = this.state;
const { attachLogs } = this.state;
const { form } = this;
const {
onCancel, isSubmitting, isCompressing,
logFiles, error, onDownload, isDownloading,
logFiles, error, onDownload, isDownloading, isSubmittingBugReport
} = this.props;

const submitManuallyLink = intl.formatMessage(messages.submitManuallyLink);
Expand All @@ -250,12 +248,12 @@ export default class BugReportDialog extends Component<Props, State> {

const attachedLogsClasses = classnames([
styles.attachedLogs,
(showLogs && logFiles) ? styles.show : null,
(attachLogs && logFiles) ? styles.show : null,
]);

const submitButtonClasses = classnames([
'submitButton',
(isSubmitting || isCompressing) ? styles.isSubmitting : null,
isSubmittingBugReport ? styles.isSubmitting : null,
]);

const downloadButtonClasses = classnames([
Expand All @@ -272,8 +270,8 @@ export default class BugReportDialog extends Component<Props, State> {
className: submitButtonClasses,
label: this.context.intl.formatMessage(messages.submitButtonLabel),
primary: true,
disabled: isSubmitting,
onClick: this.submit.bind(this, null),
disabled: isSubmittingBugReport,
onClick: this.submit,
},
];

Expand All @@ -299,8 +297,13 @@ export default class BugReportDialog extends Component<Props, State> {
title={intl.formatMessage(messages.title)}
actions={!error ? actions : alternativeActions}
closeOnOverlayClick
onClose={onCancel}
closeButton={<DialogCloseButton onClose={onCancel} />}
onClose={this.onClose}
closeButton={
<DialogCloseButton
disabled={isSubmittingBugReport}
onClose={this.onClose}
/>
}
>
{error ? (
<div>
Expand Down Expand Up @@ -356,7 +359,7 @@ export default class BugReportDialog extends Component<Props, State> {
<Checkbox
onChange={this.handleLogsSwitchToggle}
label={intl.formatMessage(messages.logsSwitchPlaceholder)}
checked={showLogs}
checked={attachLogs}
skin={<SimpleSwitchSkin />}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

button {
cursor: pointer;
letter-spacing: 1px;
}

p {
Expand Down
Loading