nost-tools 2.3.0__py3-none-any.whl → 2.4.0__py3-none-any.whl

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.

Potentially problematic release.


This version of nost-tools might be problematic. Click here for more details.

nost_tools/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "2.3.0"
1
+ __version__ = "2.4.0"
2
2
 
3
3
  from .application import Application
4
4
  from .application_utils import ConnectionConfig, ModeStatusObserver, TimeStatusPublisher
nost_tools/application.py CHANGED
@@ -4,6 +4,7 @@ Provides a base application that publishes messages from a simulator to a broker
4
4
 
5
5
  import functools
6
6
  import logging
7
+ import logging.handlers
7
8
  import os
8
9
  import signal
9
10
  import ssl
@@ -308,6 +309,17 @@ class Application:
308
309
  self.shut_down_when_terminated = getattr(
309
310
  parameters, "shut_down_when_terminated", shut_down_when_terminated
310
311
  )
312
+
313
+ # Configure file logging if requested
314
+ if getattr(parameters, "enable_file_logging", False):
315
+ self.configure_file_logging(
316
+ log_dir=getattr(parameters, "log_dir", None),
317
+ log_filename=getattr(parameters, "log_filename", None),
318
+ log_level=getattr(parameters, "log_level", None),
319
+ max_bytes=getattr(parameters, "max_bytes", None),
320
+ backup_count=getattr(parameters, "backup_count", None),
321
+ log_format=getattr(parameters, "log_format", None),
322
+ )
311
323
  else:
312
324
  logger.warning("No parameters found in configuration, using defaults")
313
325
  self.set_offset = set_offset
@@ -1475,9 +1487,67 @@ class Application:
1475
1487
 
1476
1488
  def _create_shut_down_observer(self) -> None:
1477
1489
  """
1478
- Creates an observer to shut down the application when the simulation is terminated.
1490
+ Creates a shut down observer to close the application when the simulator is terminated.
1479
1491
  """
1480
1492
  if self._shut_down_observer is not None:
1481
1493
  self.simulator.remove_observer(self._shut_down_observer)
1482
1494
  self._shut_down_observer = ShutDownObserver(self)
1483
1495
  self.simulator.add_observer(self._shut_down_observer)
1496
+
1497
+ def configure_file_logging(
1498
+ self,
1499
+ log_dir: str = None,
1500
+ log_filename: str = None,
1501
+ log_level: str = None,
1502
+ max_bytes: int = None,
1503
+ backup_count: int = None,
1504
+ log_format: str = None,
1505
+ ):
1506
+ """
1507
+ Configures file logging for the application.
1508
+
1509
+ Args:
1510
+ log_dir (str): Directory where log files will be stored
1511
+ log_filename (str): Name of the log file. If None, a timestamped filename will be used
1512
+ log_level (str): Logging level (e.g., 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
1513
+ max_bytes (int): Maximum file size in bytes before rotating
1514
+ backup_count (int): Number of backup files to keep
1515
+ log_format (str): Log message format
1516
+ """
1517
+ try:
1518
+ if log_filename is None:
1519
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
1520
+ log_filename = os.path.join(log_dir, f"{self.app_name}_{timestamp}.log")
1521
+ else:
1522
+ log_filename = os.path.join(log_dir, log_filename)
1523
+
1524
+ # Create log directory if it doesn't exist
1525
+ if log_dir and not os.path.exists(log_dir):
1526
+ os.makedirs(log_dir)
1527
+ logger.info(f"Log directory {log_dir} successfully created.")
1528
+
1529
+ # Configure rotating file handler
1530
+ handler = logging.handlers.RotatingFileHandler(
1531
+ log_filename, maxBytes=max_bytes, backupCount=backup_count
1532
+ )
1533
+
1534
+ # Set log level
1535
+ level = getattr(logging, log_level.upper(), logging.INFO)
1536
+ handler.setLevel(level)
1537
+
1538
+ # Set log format
1539
+ if log_format is not None:
1540
+ formatter = logging.Formatter(log_format)
1541
+ handler.setFormatter(formatter)
1542
+ else:
1543
+ # Default format
1544
+ formatter = logging.Formatter(
1545
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
1546
+ )
1547
+ handler.setFormatter(formatter)
1548
+
1549
+ # Add the handler to the root logger
1550
+ logging.getLogger().addHandler(handler)
1551
+ logger.info(f"File logging configured: {log_filename} (level: {log_level})")
1552
+ except Exception as e:
1553
+ logger.error(f"Error configuring file logging: {e}")
nost_tools/manager.py CHANGED
@@ -164,7 +164,7 @@ class Manager(Application):
164
164
  set_offset: bool = True,
165
165
  time_status_step: timedelta = None,
166
166
  time_status_init: datetime = None,
167
- shut_down_when_terminated: bool = False,
167
+ shut_down_when_terminated: bool = False
168
168
  ) -> None:
169
169
  """
170
170
  Starts up the application by connecting to message broker, starting a background event loop,
nost_tools/schemas.py CHANGED
@@ -280,7 +280,7 @@ class KeycloakConfig(BaseModel):
280
280
  realm: str = Field("master", description="Keycloak realm.")
281
281
  tls: bool = Field(False, description="Keycloak TLS/SSL.")
282
282
  token_refresh_interval: int = Field(
283
- 60, description="Keycloak token refresh interval, in seconds."
283
+ 240, description="Keycloak token refresh interval, in seconds."
284
284
  )
285
285
 
286
286
 
@@ -337,7 +337,35 @@ class TimeScaleUpdateSchema(BaseModel):
337
337
  )
338
338
 
339
339
 
340
- class ManagerConfig(BaseModel):
340
+ class LoggingConfig(BaseModel):
341
+ """
342
+ Configuration for logging.
343
+ """
344
+
345
+ enable_file_logging: Optional[bool] = Field(
346
+ False, description="Enable file logging."
347
+ )
348
+ log_dir: Optional[str] = Field(
349
+ "logs", description="Directory path for log files."
350
+ )
351
+ log_filename: Optional[str] = Field(None, description="Path to the log file.")
352
+ log_level: Optional[str] = Field(
353
+ "INFO", description="Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)."
354
+ )
355
+ max_bytes: Optional[int] = Field(
356
+ 10 * 1024 * 1024,
357
+ description="Maximum size of the log file in bytes. Default is 10MB.",
358
+ )
359
+ backup_count: Optional[int] = Field(
360
+ 5, description="Number of backup log files to keep."
361
+ )
362
+ log_format: Optional[str] = Field(
363
+ "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
364
+ description="Format of the log messages.",
365
+ )
366
+
367
+
368
+ class ManagerConfig(LoggingConfig):
341
369
  sim_start_time: Optional[datetime] = Field(
342
370
  None, description="Simulation start time."
343
371
  )
@@ -405,7 +433,7 @@ class ManagerConfig(BaseModel):
405
433
  return values
406
434
 
407
435
 
408
- class ManagedApplicationConfig(BaseModel):
436
+ class ManagedApplicationConfig(LoggingConfig):
409
437
  time_scale_factor: float = Field(1.0, description="Time scale factor.")
410
438
  time_step: timedelta = Field(
411
439
  timedelta(seconds=1), description="Time step for swe_change."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nost_tools
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: Tools for Novel Observing Strategies Testbed (NOS-T) Applications
5
5
  Author-email: "Paul T. Grogan" <paul.grogan@asu.edu>, "Emmanuel M. Gonzalez" <emmanuelgonzalez@asu.edu>
6
6
  License-Expression: BSD-3-Clause
@@ -1,18 +1,18 @@
1
- nost_tools/__init__.py,sha256=5DeYQxWXibC9y__BvjwL8YC8K4EYMZbAV6E75k5nuL8,870
2
- nost_tools/application.py,sha256=gh48fokVifuhKyAoJylZ2mF_WHW90G9L8j99Ct7j2Pg,64257
1
+ nost_tools/__init__.py,sha256=PHcnb5Yc5yUfKYuHt2GDCto5nsYeqZwpA7cVQBOHNZI,870
2
+ nost_tools/application.py,sha256=YCLE17NZzkk12gPCJjlXVCtaf2cUWoYG2qMoEPhwRR4,67274
3
3
  nost_tools/application_utils.py,sha256=jiMzuuP6-47UlUO64HhwNvbl6uKvVnsksYgOw7CmxL4,9327
4
4
  nost_tools/configuration.py,sha256=4WLs1BrHMMvVhSIpJfjVZe-zw04WygAzjiLX2pVXibY,13146
5
5
  nost_tools/entity.py,sha256=JrSN5rz7h-N9zIQsaJOQVBIYPDfygacedks55fsq_QQ,2802
6
6
  nost_tools/errors.py,sha256=0JcDlMEkZAya3-5c0rRozLuxp8qF58StG4JgRsaxfKU,344
7
7
  nost_tools/logger_application.py,sha256=rxPBfyA7Zym5b_EsoSJvT9JWNIVWZX1a-4czFwCqaQ4,7217
8
8
  nost_tools/managed_application.py,sha256=Xa6qGsNVrr_XNnpJt_-L5PVnpeUy7GXIf0p2aEI4dSE,11673
9
- nost_tools/manager.py,sha256=KqFyE-vv9dPRuVdz_r1SAsPeWt9LwKOTF-a2cJId0rY,24321
9
+ nost_tools/manager.py,sha256=nW74aER5K-8ad8FUb1-QKQbJAY3v-crvp1iWYpjv6DQ,24320
10
10
  nost_tools/observer.py,sha256=D64V0KTvHRPEqbB8q3BosJhoAlpBah2vyBlVbxWQR44,8161
11
11
  nost_tools/publisher.py,sha256=omU8tb0AXnA6RfhYSh0vnXbJtrRo4ukx1J5ANl4bDLQ,5291
12
- nost_tools/schemas.py,sha256=RZH9LCWSZT8hGteI_Cc5a_w_TyFYx0Kh5mBM02SObrk,20575
12
+ nost_tools/schemas.py,sha256=39vbVG0G81vnoJ6YoHLCzz2_g3ZTtn8L3gxPQ5ttCYA,21499
13
13
  nost_tools/simulator.py,sha256=pWfMSarMCuInQTlvlJ5l53w5ZZP6jjyUtY8uWOkbe-4,20062
14
- nost_tools-2.3.0.dist-info/licenses/LICENSE,sha256=aAMU-mTHTKpWkBsg9QhkhCQpEm3Gri7J_fVuJov8s3s,1539
15
- nost_tools-2.3.0.dist-info/METADATA,sha256=6ovwTQnDSv0ODsIsMQcFI5-kN652WW8FYOYlwzg-SH8,4256
16
- nost_tools-2.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- nost_tools-2.3.0.dist-info/top_level.txt,sha256=LNChUgrv2-wiym12O0r61kY83COjTpTiJ2Ly1Ca58A8,11
18
- nost_tools-2.3.0.dist-info/RECORD,,
14
+ nost_tools-2.4.0.dist-info/licenses/LICENSE,sha256=aAMU-mTHTKpWkBsg9QhkhCQpEm3Gri7J_fVuJov8s3s,1539
15
+ nost_tools-2.4.0.dist-info/METADATA,sha256=1zLzpRY32Q1xrd_sJiowqEMvY3lsL8VhcYkMOx_wj1E,4256
16
+ nost_tools-2.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ nost_tools-2.4.0.dist-info/top_level.txt,sha256=LNChUgrv2-wiym12O0r61kY83COjTpTiJ2Ly1Ca58A8,11
18
+ nost_tools-2.4.0.dist-info/RECORD,,