diff --git a/CHANGELOG.md b/CHANGELOG.md index aef8453d..6bc25e3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). The format is based on [Keep a Changelog](http://keepachangelog.com/). +## Version 1.4.0 - tbd + +### Added + +- TODO + +### Fixed + +- Remove stack from log message, if present + ## Version 1.3.1 - 2025-04-30 ### Fixed diff --git a/lib/logging/index.js b/lib/logging/index.js index c5463723..6d77d766 100644 --- a/lib/logging/index.js +++ b/lib/logging/index.js @@ -122,6 +122,8 @@ module.exports = resource => { attributes['exception.message'] = e.message attributes['exception.stacktrace'] = e.stack attributes['exception.type'] = e.name + // remove stack from message, if present + log.msg = log.msg.replace(e.stack, e.stack.split('\n')[0]) } for (const field of custom_fields) if (field in log) attributes[field] = log[field] logger.emit({ diff --git a/test/bookshop/srv/admin-service.js b/test/bookshop/srv/admin-service.js index 5923cf59..fb1cdf6c 100644 --- a/test/bookshop/srv/admin-service.js +++ b/test/bookshop/srv/admin-service.js @@ -18,6 +18,7 @@ module.exports = class AdminService extends cds.ApplicationService { err.foo = 'bar' cds.log('AdminService').error('Oh no!', err) } + cds.log('AdminService').error({ message: 'Error-like oh no!', foo: 'bar' }, new Error('dummy')) }) this.on('test_spawn', () => { diff --git a/test/logging.test.js b/test/logging.test.js index 645068a5..1a769e86 100644 --- a/test/logging.test.js +++ b/test/logging.test.js @@ -42,7 +42,7 @@ describe('logging', () => { const { status } = await GET('/odata/v4/admin/Genres', admin) expect(status).to.equal(200) const logs = console.dir.mock.calls.map(([log]) => log) - expect(logs.length).to.equal(3) + expect(logs.length).to.equal(4) expect(logs[0]).to.include({ body: 'GET /odata/v4/admin/Genres ' }) //> why the trailing space? expect(logs[1]).to.include({ body: 'Hello, World!' }) expect(logs[2]).to.containSubset({ @@ -50,13 +50,20 @@ describe('logging', () => { attributes: { 'log.type': 'LogRecord', 'exception.message': "Cannot read properties of undefined (reading 'exist')", - 'exception.stacktrace': s => - cds.version.split('.')[0] < 9 - ? s.match(/^TypeError: .+(\n\s+at .+){6}$/) - : s.match(/^TypeError: .+(\n\s+at .+){5}$/), + 'exception.stacktrace': s => s.match(/^TypeError: .+(\n\s+at .+){5,}$/), 'exception.type': 'TypeError', foo: 'bar' } }) + expect(logs[3]).to.containSubset({ + body: 'Error-like oh no! Error: dummy', + attributes: { + 'log.type': 'LogRecord', + 'exception.message': 'dummy', + 'exception.stacktrace': s => s.match(/^Error: .+(\n\s+at .+){5,}$/), + 'exception.type': 'Error', + foo: 'bar' + } + }) }) })