@alwaysai/device-agent 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/lib/application-control/backup.d.ts.map +1 -1
  2. package/lib/application-control/backup.js +4 -3
  3. package/lib/application-control/backup.js.map +1 -1
  4. package/lib/application-control/install.d.ts.map +1 -1
  5. package/lib/application-control/install.js +6 -5
  6. package/lib/application-control/install.js.map +1 -1
  7. package/lib/application-control/models.d.ts.map +1 -1
  8. package/lib/application-control/models.js +3 -2
  9. package/lib/application-control/models.js.map +1 -1
  10. package/lib/application-control/status.d.ts.map +1 -1
  11. package/lib/application-control/status.js +6 -5
  12. package/lib/application-control/status.js.map +1 -1
  13. package/lib/application-control/utils.d.ts.map +1 -1
  14. package/lib/application-control/utils.js +3 -2
  15. package/lib/application-control/utils.js.map +1 -1
  16. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +3 -3
  17. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  18. package/lib/cloud-connection/device-agent-cloud-connection.js +90 -50
  19. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  20. package/lib/cloud-connection/device-agent.d.ts +21 -0
  21. package/lib/cloud-connection/device-agent.d.ts.map +1 -0
  22. package/lib/cloud-connection/device-agent.js +69 -0
  23. package/lib/cloud-connection/device-agent.js.map +1 -0
  24. package/lib/endpoints.d.ts +3 -0
  25. package/lib/endpoints.d.ts.map +1 -0
  26. package/lib/endpoints.js +28 -0
  27. package/lib/endpoints.js.map +1 -0
  28. package/lib/environment.d.ts +1 -0
  29. package/lib/environment.d.ts.map +1 -1
  30. package/lib/environment.js +2 -1
  31. package/lib/environment.js.map +1 -1
  32. package/lib/index.js +2 -1
  33. package/lib/index.js.map +1 -1
  34. package/lib/infrastructure/certificates-and-tokens.d.ts +1 -1
  35. package/lib/infrastructure/certificates-and-tokens.d.ts.map +1 -1
  36. package/lib/infrastructure/certificates-and-tokens.js +13 -39
  37. package/lib/infrastructure/certificates-and-tokens.js.map +1 -1
  38. package/lib/subcommands/app/app.d.ts.map +1 -1
  39. package/lib/subcommands/app/app.js +6 -5
  40. package/lib/subcommands/app/app.js.map +1 -1
  41. package/lib/subcommands/device/device.d.ts.map +1 -1
  42. package/lib/subcommands/device/device.js +31 -22
  43. package/lib/subcommands/device/device.js.map +1 -1
  44. package/lib/subcommands/get-model-package.d.ts.map +1 -1
  45. package/lib/subcommands/get-model-package.js +2 -1
  46. package/lib/subcommands/get-model-package.js.map +1 -1
  47. package/lib/util/directories.d.ts +15 -0
  48. package/lib/util/directories.d.ts.map +1 -1
  49. package/lib/util/directories.js +19 -4
  50. package/lib/util/directories.js.map +1 -1
  51. package/lib/util/http-client.d.ts +3 -0
  52. package/lib/util/http-client.d.ts.map +1 -0
  53. package/lib/util/http-client.js +30 -0
  54. package/lib/util/http-client.js.map +1 -0
  55. package/lib/util/logger.d.ts +4 -0
  56. package/lib/util/logger.d.ts.map +1 -0
  57. package/lib/util/logger.js +25 -0
  58. package/lib/util/logger.js.map +1 -0
  59. package/package.json +2 -1
  60. package/src/application-control/backup.ts +4 -3
  61. package/src/application-control/install.ts +6 -5
  62. package/src/application-control/models.ts +4 -3
  63. package/src/application-control/status.ts +6 -5
  64. package/src/application-control/utils.ts +3 -2
  65. package/src/cloud-connection/device-agent-cloud-connection.ts +175 -81
  66. package/src/cloud-connection/device-agent.ts +122 -0
  67. package/src/endpoints.ts +24 -0
  68. package/src/environment.ts +1 -0
  69. package/src/index.ts +2 -1
  70. package/src/infrastructure/certificates-and-tokens.ts +31 -49
  71. package/src/subcommands/app/app.ts +6 -5
  72. package/src/subcommands/device/device.ts +67 -30
  73. package/src/subcommands/get-model-package.ts +2 -1
  74. package/src/util/directories.ts +49 -6
  75. package/src/util/http-client.ts +35 -0
  76. package/src/util/logger.ts +28 -0
@@ -1,24 +1,33 @@
1
- import { DeviceTokens, writeOrUpdateDeviceCfgFile } from 'alwaysai/lib/components/device';
2
- import { checkUserIsLoggedInComponent } from 'alwaysai/lib/components/user';
3
- import { LOCAL_AAI_CFG_DIR, LOCAL_CERT_AND_KEY_DIR } from 'alwaysai/lib/constants';
4
- import { checkPaidPlan } from 'alwaysai/lib/core/project';
5
1
  import {
6
- CliRpcClient,
7
- getDeviceCertificates,
8
- IotRpcDevice,
9
- refreshDevice,
10
- } from 'alwaysai/lib/infrastructure';
11
- import { JsSpawner, Spawner, writeCertificate, writeTokens } from 'alwaysai/lib/util';
2
+ DeviceTokens,
3
+ writeOrUpdateDeviceCfgFile,
4
+ } from "alwaysai/lib/components/device";
5
+ import { checkUserIsLoggedInComponent } from "alwaysai/lib/components/user";
6
+ import {
7
+ LOCAL_AAI_CFG_DIR,
8
+ LOCAL_CERT_AND_KEY_DIR,
9
+ } from "alwaysai/lib/constants";
10
+ import { checkPaidPlan } from "alwaysai/lib/core/project";
11
+ import {
12
+ JsSpawner,
13
+ Spawner,
14
+ writeCertificate,
15
+ writeTokens,
16
+ } from "alwaysai/lib/util";
17
+ import { logger } from "../util/logger";
12
18
 
13
19
  // NOTE: This is reimplemented from the CLI to work for local checks
14
20
  export async function getTargetHardwareUuid(spawner: Spawner) {
15
- if (await spawner.exists('/var/lib/dbus/machine-id')) {
16
- return await spawner.run({ exe: 'cat', args: ['/var/lib/dbus/machine-id'] });
21
+ if (await spawner.exists("/var/lib/dbus/machine-id")) {
22
+ return await spawner.run({
23
+ exe: "cat",
24
+ args: ["/var/lib/dbus/machine-id"],
25
+ });
17
26
  }
18
- if (await spawner.exists('/etc/machine-id')) {
19
- return await spawner.run({ exe: 'cat', args: ['/etc/machine-id'] });
27
+ if (await spawner.exists("/etc/machine-id")) {
28
+ return await spawner.run({ exe: "cat", args: ["/etc/machine-id"] });
20
29
  }
21
- return await spawner.run({ exe: 'hostname' });
30
+ return await spawner.run({ exe: "hostname" });
22
31
  }
23
32
 
24
33
  // NOTE: This closely follows the flow of deviceCheckAndUpdateComponent in the CLI
@@ -26,46 +35,19 @@ export async function writeCertificateAndToken(props: { deviceUuid: string }) {
26
35
  const { deviceUuid } = props;
27
36
  await checkUserIsLoggedInComponent({ yes: true });
28
37
  if (!(await checkPaidPlan())) {
29
- throw new Error(`This action only supported for Enterprise alwaysAI accounts!`);
30
- }
31
- const device: IotRpcDevice = (await CliRpcClient().getDeviceByUUID({
32
- uuid: deviceUuid,
33
- })) as IotRpcDevice;
34
- if (!device) {
35
- throw new Error(`Device not found for deviceId=${deviceUuid}`);
38
+ throw new Error(
39
+ `This action only supported for Enterprise alwaysAI accounts!`
40
+ );
36
41
  }
37
- // TODO: Update HW ID if not there
38
- if (device.hardware_ids && device.hardware_ids !== '') {
39
- const spawner = JsSpawner();
40
- const hardwareId = await getTargetHardwareUuid(spawner);
41
- if (hardwareId !== device.hardware_ids) {
42
- throw new Error('Certificates not intended for this device!');
43
- }
44
- }
45
- const response = await refreshDevice(device.uuid);
46
42
  const tokens: DeviceTokens = {
47
43
  deviceId: deviceUuid,
48
- accessToken: response.accessToken,
49
- refreshToken: response.refreshToken,
50
- idToken: response.idToken,
44
+ accessToken: "",
45
+ refreshToken: "",
46
+ idToken: "",
51
47
  };
52
48
  const tokenSpawner = JsSpawner({ path: LOCAL_AAI_CFG_DIR });
53
49
  await writeTokens({ spawner: tokenSpawner, tokens });
54
50
  await writeOrUpdateDeviceCfgFile({ spawner: tokenSpawner });
55
51
 
56
- let iotKeys = device.iot_keys;
57
- if (!iotKeys) {
58
- // there are no certificates, we need to generate new ones
59
- console.log('Generating new certificate');
60
- const response = await getDeviceCertificates(device.uuid, device.mode);
61
- iotKeys = response.iotKeys;
62
- }
63
- const certSpawner = JsSpawner({ path: LOCAL_CERT_AND_KEY_DIR });
64
- await writeCertificate({
65
- spawner: certSpawner,
66
- certificate: iotKeys.certificatePem,
67
- privateKey: iotKeys.keyPair.PrivateKey,
68
- rootCa: iotKeys.rootCA,
69
- });
70
- console.log('Updated tokens and certificate');
52
+ logger.info("Updated tokens and certificate");
71
53
  }
@@ -24,6 +24,7 @@ import {
24
24
  updateModels,
25
25
  } from '../../application-control';
26
26
  import { AgentConfigFile } from '../../infrastructure/agent-config';
27
+ import { logger } from '../../util/logger';
27
28
 
28
29
  export const listAppsCliLeaf = CliLeaf({
29
30
  name: 'list',
@@ -47,7 +48,7 @@ export const listAppReleasesCliLeaf = CliLeaf({
47
48
  async action(_, opts) {
48
49
  const { project } = opts;
49
50
  const releaseHistory = await listAppReleases({ projectId: project });
50
- console.log(releaseHistory);
51
+ logger.info(releaseHistory);
51
52
  },
52
53
  });
53
54
 
@@ -66,7 +67,7 @@ export const listAppLatestReleaseCliLeaf = CliLeaf({
66
67
  if (latestReleaseHash === undefined) {
67
68
  throw new CliTerseError('This application has not been published yet');
68
69
  }
69
- console.log(latestReleaseHash);
70
+ logger.info(latestReleaseHash);
70
71
  },
71
72
  });
72
73
 
@@ -107,7 +108,7 @@ export const getAppStatusCliLeaf = CliLeaf({
107
108
  async action(_, opts) {
108
109
  const { project } = opts;
109
110
  const appStatus = await getAppStatus({ projectId: project });
110
- console.log(appStatus);
111
+ logger.info(appStatus);
111
112
  },
112
113
  });
113
114
 
@@ -143,7 +144,7 @@ export const getAppLogsCliLeaf = CliLeaf({
143
144
  const readable = await getAppLogs({ projectId: project });
144
145
  readable.setEncoding('utf8');
145
146
  for await (const chunk of readable) {
146
- console.log(chunk);
147
+ logger.info(chunk);
147
148
  }
148
149
  },
149
150
  });
@@ -307,7 +308,7 @@ export const getAllEnvsCLiLeaf = CliLeaf({
307
308
  },
308
309
  async action(_, opts) {
309
310
  const { project } = opts;
310
- console.log(await getAllEnvs({ projectId: project }));
311
+ logger.info(await getAllEnvs({ projectId: project }));
311
312
  },
312
313
  });
313
314
 
@@ -1,62 +1,99 @@
1
- import { CliLeaf, CliStringInput } from '@alwaysai/alwayscli';
2
- import { checkUserIsLoggedInComponent } from 'alwaysai/lib/components/user';
3
- import { checkPaidPlan } from 'alwaysai/lib/core/project';
4
- import { addDevice, CliAuthenticationClient } from 'alwaysai/lib/infrastructure';
5
- import { JsSpawner } from 'alwaysai/lib/util';
6
- import { getCpuUtil, getDiskUtil, getMemUtil } from '../../device-control/device-control';
1
+ import { CliLeaf, CliStringInput } from "@alwaysai/alwayscli";
2
+ import { checkUserIsLoggedInComponent } from "alwaysai/lib/components/user";
3
+ import { checkPaidPlan } from "alwaysai/lib/core/project";
4
+ import { v4 as uuidv4 } from "uuid";
5
+ import { CliAuthenticationClient } from "alwaysai/lib/infrastructure";
6
+
7
+ import { httpClient, microServiceHttpClient } from "../../util/http-client";
8
+ import {
9
+ AWS_ROOT_CERTIFICATE_FILE_NAME,
10
+ BOOTSTRAP_CERTIFICATES_DIR_PATH,
11
+ } from "../../util/directories";
12
+
13
+ import { LOCAL_CERT_AND_KEY_DIR } from "alwaysai/lib/constants";
14
+ import fetch from "node-fetch";
15
+ import { JsSpawner } from "alwaysai/lib/util";
16
+ import {
17
+ getCpuUtil,
18
+ getDiskUtil,
19
+ getMemUtil,
20
+ } from "../../device-control/device-control";
7
21
  import {
8
22
  getTargetHardwareUuid,
9
23
  writeCertificateAndToken,
10
- } from '../../infrastructure/certificates-and-tokens';
24
+ } from "../../infrastructure/certificates-and-tokens";
25
+ import { logger } from "../../util/logger";
11
26
 
12
27
  export const initCliLeaf = CliLeaf({
13
- name: 'init',
14
- description: 'Initialize device',
28
+ name: "init",
29
+ description: "Initialize device",
15
30
  namedInputs: {
16
31
  name: CliStringInput({
17
- description: 'Device name',
32
+ description: "Device name",
18
33
  required: true,
19
34
  }),
20
35
  description: CliStringInput({
21
- description: 'Device description',
36
+ description: "Device description",
22
37
  required: false,
23
38
  }),
24
39
  },
25
40
  async action(_, opts) {
26
41
  const { name, description } = opts;
27
- console.log('Initializing device');
42
+ logger.info("Initializing device");
28
43
  await checkUserIsLoggedInComponent({ yes: true });
29
44
  if (!(await checkPaidPlan())) {
30
- throw new Error(`This action only supported for Enterprise alwaysAI accounts!`);
45
+ throw new Error(
46
+ `This action only supported for Enterprise alwaysAI accounts!`
47
+ );
31
48
  }
32
49
  const { username } = await CliAuthenticationClient().getInfo();
33
50
  const spawner = JsSpawner();
34
51
  const hardwareId = await getTargetHardwareUuid(spawner);
35
- const deviceToAdd = {
36
- owner: username,
37
- friendly_name: name,
38
- host_name: '',
39
- device_user_name: '',
40
- description: description || '',
41
- hardware_ids: hardwareId,
42
- device_hash: '',
43
- iotKeys: '',
52
+ const device = {
53
+ deviceMode: "production",
54
+ hardwareId,
55
+ txId: uuidv4(),
56
+ userName: username,
57
+ friendlyName: name,
44
58
  };
45
- const response = await addDevice(deviceToAdd, 'production');
46
- await writeCertificateAndToken({ deviceUuid: response.deviceUUID });
47
- console.log(`Initialized device as ${response.deviceUUID}`);
59
+
60
+ const response = await microServiceHttpClient(
61
+ "fleet-provision",
62
+ "addDevice",
63
+ "POST",
64
+ JSON.stringify(device)
65
+ );
66
+
67
+ const ROOT_CERT_AWS = await httpClient(
68
+ "https://www.amazontrust.com/repository/AmazonRootCA1.pem",
69
+ "GET"
70
+ );
71
+
72
+ await writeCertificateAndToken({ deviceUuid: response.deviceUuid });
73
+
74
+ await JsSpawner().mkdirp(BOOTSTRAP_CERTIFICATES_DIR_PATH);
75
+ JsSpawner({ path: LOCAL_CERT_AND_KEY_DIR }).writeFile(
76
+ AWS_ROOT_CERTIFICATE_FILE_NAME,
77
+ ROOT_CERT_AWS
78
+ );
79
+ const certSpawner = JsSpawner({ path: BOOTSTRAP_CERTIFICATES_DIR_PATH });
80
+ for (const key in response.claimCertificate) {
81
+ await certSpawner.writeFile(key, response.claimCertificate[key]);
82
+ }
83
+
84
+ logger.info(`Initialized device as ${response.deviceUuid}`);
48
85
  },
49
86
  });
50
87
 
51
88
  export const getInfoCliLeaf = CliLeaf({
52
- name: 'get-info',
53
- description: 'Get device info',
89
+ name: "get-info",
90
+ description: "Get device info",
54
91
  namedInputs: {},
55
92
  async action(_, opts) {
56
93
  const deviceInfo = [
57
- ['CPU Utilization', `${String(await getCpuUtil())} %`],
58
- ['Disk Utilization', `${String(await getDiskUtil())} %`],
59
- ['Memory Utilization', `${String(await getMemUtil())} %`],
94
+ ["CPU Utilization", `${String(await getCpuUtil())} %`],
95
+ ["Disk Utilization", `${String(await getDiskUtil())} %`],
96
+ ["Memory Utilization", `${String(await getMemUtil())} %`],
60
97
  ];
61
98
  console.table(deviceInfo);
62
99
  },
@@ -2,6 +2,7 @@ import { CliLeaf, CliNumberInput, CliStringInput } from '@alwaysai/alwayscli';
2
2
  import { appInstallModel } from 'alwaysai/lib/core/app';
3
3
  import { CliRpcClient } from 'alwaysai/lib/infrastructure';
4
4
  import { JsSpawner } from 'alwaysai/lib/util';
5
+ import { logger } from '../util/logger';
5
6
 
6
7
  export const getModelPackageCliLeaf = CliLeaf({
7
8
  name: 'get-model-package',
@@ -27,6 +28,6 @@ export const getModelPackageCliLeaf = CliLeaf({
27
28
  const version =
28
29
  opts.version || (await CliRpcClient().getModelVersion({ id })).version;
29
30
  await appInstallModel(spawner, id, version);
30
- console.log(`Completed downloading ${id} to ${path}`);
31
+ logger.info(`Completed downloading ${id} to ${path}`);
31
32
  },
32
33
  });
@@ -1,12 +1,23 @@
1
1
  import {
2
- DEVICE_CERTIFICATE_FILE_NAME,
3
- DEVICE_PRIVATE_KEY_FILE_NAME,
4
- DEVICE_ROOT_CERT_FILE_NAME,
5
2
  DEVICE_TOKEN_FILE_NAME,
6
3
  LOCAL_AAI_CFG_DIR,
7
4
  LOCAL_CERT_AND_KEY_DIR,
8
- } from 'alwaysai/lib/constants';
9
- import { join } from 'path';
5
+ } from "alwaysai/lib/constants";
6
+ import { join } from "path";
7
+
8
+ export const BOOTSTRAP_DIR_NAME = "bootstrap-certificates";
9
+ export const BOOTSTRAP_DEVICE_PRIVATE_KEY_FILE_NAME =
10
+ "aai-claim-private-key_qa.pem.key";
11
+ export const BOOTSTRAP_DEVICE_CERTIFICATE_FILE_NAME =
12
+ "aai-claim-cert_qa.pem.crt";
13
+ export const BOOTSTRAP_CLAIM_ID_FILE_NAME = "aai-claim-cert-id_qa.txt";
14
+ export const AWS_ROOT_CERTIFICATE_FILE_NAME = "AmazonRootCA1.pem";
15
+ export const CERTIFICATE_OWNERSHIP_TOKEN_FILE_NAME =
16
+ "certificate-ownership-token.txt";
17
+
18
+ export const DEVICE_PRIVATE_KEY_FILE_NAME = "aai-claim-private-key_qa.pem.key";
19
+ export const DEVICE_CERTIFICATE_FILE_NAME = "aai-claim-cert_qa.pem.crt";
20
+ export const DEVICE_CLAIM_ID_FILE_NAME = "aai-claim-cert-id_qa.txt";
10
21
 
11
22
  export function getPrivateKeyFilePath() {
12
23
  return join(LOCAL_CERT_AND_KEY_DIR, DEVICE_PRIVATE_KEY_FILE_NAME);
@@ -17,9 +28,41 @@ export function getCertificateFilePath() {
17
28
  }
18
29
 
19
30
  export function getRootCertificateFilePath() {
20
- return join(LOCAL_CERT_AND_KEY_DIR, DEVICE_ROOT_CERT_FILE_NAME);
31
+ return join(LOCAL_CERT_AND_KEY_DIR, AWS_ROOT_CERTIFICATE_FILE_NAME);
21
32
  }
22
33
 
23
34
  export function getCredentialsFilePath() {
24
35
  return join(LOCAL_AAI_CFG_DIR, DEVICE_TOKEN_FILE_NAME);
25
36
  }
37
+
38
+ export const BOOTSTRAP_CERTIFICATES_DIR_PATH = join(
39
+ LOCAL_CERT_AND_KEY_DIR,
40
+ BOOTSTRAP_DIR_NAME
41
+ );
42
+ export const DEVICE_CLAIM_ID_FILE_PATH = join(
43
+ LOCAL_CERT_AND_KEY_DIR,
44
+ DEVICE_TOKEN_FILE_NAME
45
+ );
46
+
47
+ export const BOOTSTRAP_DEVICE_PRIVATE_KEY_FILE_PATH = join(
48
+ LOCAL_CERT_AND_KEY_DIR,
49
+ BOOTSTRAP_DIR_NAME,
50
+ BOOTSTRAP_DEVICE_PRIVATE_KEY_FILE_NAME
51
+ );
52
+
53
+ export const BOOTSTRAP_DEVICE_CERTIFICATE_FILE_PATH = join(
54
+ LOCAL_CERT_AND_KEY_DIR,
55
+ BOOTSTRAP_DIR_NAME,
56
+ BOOTSTRAP_DEVICE_CERTIFICATE_FILE_NAME
57
+ );
58
+
59
+ export const BOOTSTRAP_CLAIM_ID_FILE_PATH = join(
60
+ LOCAL_CERT_AND_KEY_DIR,
61
+ BOOTSTRAP_DIR_NAME,
62
+ BOOTSTRAP_CLAIM_ID_FILE_NAME
63
+ );
64
+
65
+ export const AWS_ROOT_CERTIFICATE_FILE_PATH = join(
66
+ LOCAL_CERT_AND_KEY_DIR,
67
+ AWS_ROOT_CERTIFICATE_FILE_NAME
68
+ );
@@ -0,0 +1,35 @@
1
+ import fetch from "node-fetch";
2
+ import { serviceEndpointBuilder } from "../endpoints";
3
+ import { CliAuthenticationClient } from "alwaysai/lib/infrastructure";
4
+
5
+ export async function httpClient(
6
+ url: string,
7
+ method: string,
8
+ data?: string,
9
+ headers?: object
10
+ ) {
11
+ const options = { method, ...(data ? { body: data } : {}) };
12
+ try {
13
+ const response = await fetch(url, options);
14
+ const code = response.status;
15
+
16
+ const contentType = response.headers.get("content-type");
17
+ if (contentType === "application/json") {
18
+ return await response.json();
19
+ } else if (contentType!.includes("text/plain")) {
20
+ return await response.text();
21
+ }
22
+ } catch (e) {}
23
+ }
24
+
25
+ export async function microServiceHttpClient(
26
+ service: string,
27
+ path: string,
28
+ method: string,
29
+ data?: string
30
+ ) {
31
+ const endpoint = serviceEndpointBuilder(service, path);
32
+ const { getIdAuthorizationHeader } = CliAuthenticationClient();
33
+ const authorizationHeader = await getIdAuthorizationHeader();
34
+ return await httpClient(endpoint, method, data);
35
+ }
@@ -0,0 +1,28 @@
1
+ import * as winston from 'winston';
2
+ import 'winston-daily-rotate-file';
3
+ import * as path from 'path';
4
+ import { AAI_DIR } from 'alwaysai/lib/constants';
5
+ import { ALWAYSAI_LOG_LEVEL, ALWAYSAI_LOG_TO_CONSOLE } from '../environment';
6
+
7
+ const LOG_LEVEL = ALWAYSAI_LOG_LEVEL || 'info';
8
+ const transports = ALWAYSAI_LOG_TO_CONSOLE
9
+ ? [new winston.transports.Console({ level: LOG_LEVEL })]
10
+ : [
11
+ new winston.transports.DailyRotateFile({
12
+ filename: path.join(AAI_DIR, 'agent-logs', 'agent-logs.txt'),
13
+ maxSize: '5m',
14
+ maxFiles: '2d',
15
+ }),
16
+ ];
17
+
18
+ export const logger = winston.createLogger({
19
+ level: LOG_LEVEL,
20
+ format: winston.format.combine(
21
+ winston.format.errors({ stack: true }),
22
+ winston.format.splat(),
23
+ winston.format.simple(),
24
+ ),
25
+ transports,
26
+ });
27
+
28
+ logger.info(`Initialized logger with log level: ${LOG_LEVEL}`);