feat: correct timezone offset on downloaded logs

This commit is contained in:
Sérgio Salgado 2021-05-25 09:54:18 +01:00 committed by Josh Harvey
parent ac3dcef35a
commit a0c77b4939
7 changed files with 74 additions and 16 deletions

View file

@ -1,18 +1,30 @@
const { parseAsync } = require('json2csv') const { parseAsync } = require('json2csv')
const moment = require('moment')
const _ = require('lodash/fp')
const logs = require('../../../logs') const logs = require('../../../logs')
const serverLogs = require('../../services/server-logs') const serverLogs = require('../../services/server-logs')
const dateFormat = (timezone, logs) => _.map(log => {
const offset = timezone.split(':')[1]
return {
...log,
timestamp: moment.utc(log.timestamp).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS')
}
}, logs)
const resolvers = { const resolvers = {
Query: { Query: {
machineLogs: (...[, { deviceId, from, until, limit, offset }]) => machineLogs: (...[, { deviceId, from, until, limit, offset }]) =>
logs.simpleGetMachineLogs(deviceId, from, until, limit, offset), logs.simpleGetMachineLogs(deviceId, from, until, limit, offset),
machineLogsCsv: (...[, { deviceId, from, until, limit, offset }]) => machineLogsCsv: (...[, { deviceId, from, until, limit, offset, timezone }]) =>
logs.simpleGetMachineLogs(deviceId, from, until, limit, offset).then(parseAsync), logs.simpleGetMachineLogs(deviceId, from, until, limit, offset)
.then(res => parseAsync(dateFormat(timezone, res))),
serverLogs: (...[, { from, until, limit, offset }]) => serverLogs: (...[, { from, until, limit, offset }]) =>
serverLogs.getServerLogs(from, until, limit, offset), serverLogs.getServerLogs(from, until, limit, offset),
serverLogsCsv: (...[, { from, until, limit, offset }]) => serverLogsCsv: (...[, { from, until, limit, offset, timezone }]) =>
serverLogs.getServerLogs(from, until, limit, offset).then(parseAsync) serverLogs.getServerLogs(from, until, limit, offset)
.then(res => parseAsync(dateFormat(timezone, res)))
} }
} }

View file

@ -1,5 +1,7 @@
const DataLoader = require('dataloader') const DataLoader = require('dataloader')
const { parseAsync } = require('json2csv') const { parseAsync } = require('json2csv')
const moment = require('moment')
const _ = require('lodash/fp')
const filters = require('../../filters') const filters = require('../../filters')
const transactions = require('../../services/transactions') const transactions = require('../../services/transactions')
@ -18,6 +20,15 @@ const txLogFields = ['txClass', 'id', 'deviceId', 'toAddress', 'cryptoAtoms',
'customerIdCardDataExpiration', 'customerIdCardData', 'customerName', 'customerIdCardDataExpiration', 'customerIdCardData', 'customerName',
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName'] 'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName']
const dateFormat = (timezone, logs) => _.map(log => {
const offset = timezone.split(':')[1]
return {
...log,
created: moment.utc(log.created).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS'),
sendTime: moment.utc(log.sendTime).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS')
}
}, logs)
const resolvers = { const resolvers = {
Customer: { Customer: {
transactions: parent => transactionsLoader.load(parent.id) transactions: parent => transactionsLoader.load(parent.id)
@ -30,11 +41,11 @@ const resolvers = {
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status), transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status),
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status }]) => transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status }]) =>
transactions.batch(from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status) transactions.batch(from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status)
.then(data => parseAsync(data, {fields: tx_logFields})), .then(data => parseAsync(data, { fields: tx_logFields, transforms: dateFormat(timezone, data) })),
transactionCsv: (...[, { id, txClass }]) => transactionCsv: (...[, { id, txClass }]) =>
transactions.getTx(id, txClass).then(parseAsync), transactions.getTx(id, txClass).then(data => parseAsync(data)),
txAssociatedDataCsv: (...[, { id, txClass }]) => txAssociatedDataCsv: (...[, { id, txClass }]) =>
transactions.getTxAssociatedData(id, txClass).then(parseAsync), transactions.getTxAssociatedData(id, txClass).then(data => parseAsync(data)),
transactionFilters: () => filters.transaction() transactionFilters: () => filters.transaction()
} }
} }

View file

@ -17,9 +17,9 @@ const typeDef = gql`
type Query { type Query {
machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] @auth machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] @auth
machineLogsCsv(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): String @auth machineLogsCsv(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int, timezone: String): String @auth
serverLogs(from: Date, until: Date, limit: Int, offset: Int): [ServerLog] @auth serverLogs(from: Date, until: Date, limit: Int, offset: Int): [ServerLog] @auth
serverLogsCsv(from: Date, until: Date, limit: Int, offset: Int): String @auth serverLogsCsv(from: Date, until: Date, limit: Int, offset: Int, timezone: String): String @auth
} }
` `

View file

@ -11,6 +11,7 @@ import { ReactComponent as Arrow } from 'src/styling/icons/arrow/download_logs.s
import { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg' import { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg'
import { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg' import { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg'
import { primaryColor, offColor, zircon } from 'src/styling/variables' import { primaryColor, offColor, zircon } from 'src/styling/variables'
import { formatDate } from 'src/utils/timezones'
import Popper from './Popper' import Popper from './Popper'
import DateRangePicker from './date-range-picker/DateRangePicker' import DateRangePicker from './date-range-picker/DateRangePicker'
@ -129,7 +130,14 @@ const useStyles = makeStyles(styles)
const ALL = 'all' const ALL = 'all'
const RANGE = 'range' const RANGE = 'range'
const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => { const LogsDownloaderPopover = ({
name,
query,
args,
title,
getLogs,
timezone
}) => {
const [selectedRadio, setSelectedRadio] = useState(ALL) const [selectedRadio, setSelectedRadio] = useState(ALL)
const [range, setRange] = useState({ from: null, until: null }) const [range, setRange] = useState({ from: null, until: null })
const [anchorEl, setAnchorEl] = useState(null) const [anchorEl, setAnchorEl] = useState(null)
@ -183,7 +191,7 @@ const LogsDownloaderPopover = ({ name, query, args, title, getLogs }) => {
const createLogsFile = (logs, range) => { const createLogsFile = (logs, range) => {
const formatDateFile = date => { const formatDateFile = date => {
return moment(date).format('YYYY-MM-DD_HH-mm') return formatDate(date, timezone, 'YYYY-MM-DD_HH-mm')
} }
const blob = new window.Blob([logs], { const blob = new window.Blob([logs], {

View file

@ -39,12 +39,14 @@ const GET_MACHINE_LOGS_CSV = gql`
$limit: Int $limit: Int
$from: DateTime $from: DateTime
$until: DateTime $until: DateTime
$timezone: String
) { ) {
machineLogsCsv( machineLogsCsv(
deviceId: $deviceId deviceId: $deviceId
limit: $limit limit: $limit
from: $from from: $from
until: $until until: $until
timezone: $timezone
) )
} }
` `
@ -114,8 +116,9 @@ const Logs = () => {
title="Download logs" title="Download logs"
name={selected.name} name={selected.name}
query={GET_MACHINE_LOGS_CSV} query={GET_MACHINE_LOGS_CSV}
args={{ deviceId }} args={{ deviceId, timezone }}
getLogs={logs => R.path(['machineLogsCsv'])(logs)} getLogs={logs => R.path(['machineLogsCsv'])(logs)}
timezone={timezone}
/> />
<Info3>{saveMessage}</Info3> <Info3>{saveMessage}</Info3>
</div> </div>

View file

@ -57,8 +57,18 @@ const SHOW_ALL = { code: 'SHOW_ALL', display: 'Show all' }
const NUM_LOG_RESULTS = 500 const NUM_LOG_RESULTS = 500
const GET_CSV = gql` const GET_CSV = gql`
query ServerData($limit: Int, $from: DateTime, $until: DateTime) { query ServerData(
serverLogsCsv(limit: $limit, from: $from, until: $until) $limit: Int
$from: DateTime
$until: DateTime
$timezone: String
) {
serverLogsCsv(
limit: $limit
from: $from
until: $until
timezone: $timezone
)
} }
` `
@ -138,8 +148,10 @@ const Logs = () => {
title="Download logs" title="Download logs"
name="server-logs" name="server-logs"
query={GET_CSV} query={GET_CSV}
args={{ timezone }}
logs={data.serverLogs} logs={data.serverLogs}
getLogs={logs => R.path(['serverLogsCsv'])(logs)} getLogs={logs => R.path(['serverLogsCsv'])(logs)}
timezone={timezone}
/> />
<Info3>{saveMessage}</Info3> <Info3>{saveMessage}</Info3>
</div> </div>

View file

@ -35,8 +35,18 @@ const GET_DATA = gql`
` `
const GET_TRANSACTIONS_CSV = gql` const GET_TRANSACTIONS_CSV = gql`
query transactions($limit: Int, $from: DateTime, $until: DateTime) { query transactions(
transactionsCsv(limit: $limit, from: $from, until: $until) $limit: Int
$from: DateTime
$until: DateTime
$timezone: String
) {
transactionsCsv(
limit: $limit
from: $from
until: $until
timezone: $timezone
)
} }
` `
@ -271,7 +281,9 @@ const Transactions = () => {
title="Download logs" title="Download logs"
name="transactions" name="transactions"
query={GET_TRANSACTIONS_CSV} query={GET_TRANSACTIONS_CSV}
args={{ timezone }}
getLogs={logs => R.path(['transactionsCsv'])(logs)} getLogs={logs => R.path(['transactionsCsv'])(logs)}
timezone={timezone}
/> />
</div> </div>
)} )}