# # Oracle APEX JS Logger: Control Your JavaScript Logs to Debug Faster and Safer

Oracle APEX JS Logger was born from the need to have JavaScript logging with two important functionalities: controlling the amount of logs displayed in console, depending on the case and the debugging being done. And the other important functionality is having logging at the production level, where errors are not reported directly and that makes debugging difficult.

- **[GitHub](https://github.com/Aftorres02/OracleAPEX_JS_Logger):** Full source code and documentation

## The Problem: console.log

When working with JavaScript, we usually use console.log for debugging. However, it can generate so much content in the console that it becomes difficult to manage, and practically impossible to use in production.


- A user reports an issue, but you can't reproduce it
- You see the error in DevTools, but users in production don't have it open
- No audit trail for user actions
- No performance metrics for slow operations
- Sensitive data might accidentally get logged

## JS-Logger, Main Features

- **Color** configuration for console
- **logger.logServer**, to log to the database using PL/SQL Logger
- Automatic data masking for sensitive fields
- **Performance timing** to find bottlenecks
- **Modules** to know where the console.log was launched from
- **Configuration according to environment** DEV, UAT, PROD


## How to Get Started

### Step 1: Load the Files

Load the files into your APEX application:

```html
#WORKSPACE_FILES#js/logger-config.js
#WORKSPACE_FILES#js/logger.js
```

### Step 2: Usage

```javascript
// Basic usage
namespace.logger.log('Application started', 'AppMain');

// With data
namespace.logger.log('User action', 'UI', {
  action: 'button_click',
  pageId: apex.env.APP_PAGE_ID
});

// For production events
namespace.logger.logServer('Payment processed', 'Payments', {
  orderId: 'ORD-123',
  amount: 99.99
});
```


## Advanced Examples

### 1. Three Log Levels with Colors

The logger provides three log levels that automatically output in different colors:

**Information (Blue)**
```javascript
namespace.logger.log('User logged in', 'Auth', { userId: 123 });
```

**Warning (Orange)**
```javascript
namespace.logger.warning('API slow', 'Network', { responseTime: 3500 });
```

**Error (Red)**
```javascript
namespace.logger.error('Validation failed', 'Form', { field: 'email' });
```

### 2. Module-Scoped Loggers

Create a logger for your module with persistent context. This is useful when building other JS libraries and you want to integrate it:

```javascript
// Create a module logger
var logger = namespace.logger.createModuleLogger('PaymentModule');

// Set context that applies to all logs from this module
logger.setExtra({ version: '2.0', feature: 'checkout' });

// Now all logs automatically include the context
logger.log('Processing payment', { amount: 99.99 });
logger.error('Payment failed', { reason: 'insufficient_funds' });

// Clear context when done
logger.clearExtra();
```


### 3. Console vs Server Logging

Three logging modes for different needs:

**Console-only** (development)
```javascript
namespace.logger.log('Debug info', 'MyModule', { data: 'value' });
```

**Console + Database** (production)
```javascript
namespace.logger.logServer('Important event', 'Business', { 
  orderId: 'ORD-123',
  action: 'order_shipped' 
});
```

**Console + Database with options** (manual control per log)
```javascript
namespace.logger.log('User completed checkout', 'Ecommerce', {
  orderId: 'ORD-123',
  total: 99.99
}, {
  sendToServer: true  // Enable server sending
});
```



### 4. Automatic Data Masking

Security is built-in. Sensitive fields are automatically masked:

```javascript
namespace.logger.log('Login attempt', 'Auth', {
  username: 'john.doe',
  password: 'secret123',  // Automatically becomes: ***MASKED***
  token: 'abc123'         // Automatically becomes: ***MASKED***
});
```

### 5. Performance Timing

Measure how long operations take:

```javascript
// Start timing
namespace.logger.timeStart('page-load');

// ... do work ...

// Stop and log elapsed time
var elapsed = namespace.logger.timeStop('page-load', 'Performance');
// Output: "page-load completed in 125.43ms"
```

## Configuration and Customization

### Turning Off and Customizing Output

To turn off logging completely we use LEVEL set to OFF.
Then depending on what we need we can use:
- **INFORMATION**: shows everything
- **WARNING**: shows warnings and errors
- **ERROR**: only errors
- **OFF**: turns off all console logs

To return to the initial configuration use `resetLevel()` or set `level: 'INFORMATION'`.

```javascript
namespace.loggerConfig.configure({
  level: 'OFF',  // OFF | ERROR | WARNING | INFORMATION
});

// Reset the level according to the main configuration
namespace.loggerConfig.resetLevel();


// Development: detailed console output
var devConfig = namespace.loggerConfig.getEnvConfig('development');
namespace.loggerConfig.configure(devConfig);

// Production: errors only, with server logging
var prodConfig = namespace.loggerConfig.getEnvConfig('production');
namespace.loggerConfig.configure(prodConfig);
```


### Other Configuration Values

```javascript
var DEFAULT_CONFIG = {
  // Logging behavior
  level:                  'INFORMATION',        // Console log level - values: OFF, ERROR, WARNING, INFORMATION
  enableServer:           true,                 // Enable server logging (database storage)

  // Server logging configuration
  serverProcessName:     'JS_LOGGER',          // APEX process name for server logging
  retryCount:             1,                    // Maximum number of retry attempts
  retryAttemptInitial:    0,                    // Initial retry attempt counter
  retryDelayBase:         1000,                 // Base delay in milliseconds

  // Default values
  defaultModuleName:      'JS_LOGGER',          // Default module name
  defaultUserName:        'UNKNOWN',            // Default user name

  // Security and data handling
  enableDataMasking:      true,                 // Enable masking of sensitive fields
  sensitiveFields:        ['password', 'token', 'ssn'],  // Fields to mask
  maxDataSize:            10000,                // Maximum data size in bytes
  maxErrorStringLength:    100,                  // Maximum error string length

  // Timing configuration
  timingDecimalPlaces:    2                     // Decimal places for timing
};
```


## Learn More

- **[Examples](https://github.com/Aftorres02/OracleAPEX_JS_Logger/tree/main/examples):** 5 focused examples covering all features
- **[Demo](https://github.com/Aftorres02/OracleAPEX_JS_Logger/tree/main/demo):** Complete payment module implementation
- **[GitHub](https://github.com/Aftorres02/OracleAPEX_JS_Logger):** Full source code and documentation
- **[Video](https://youtu.be/ktqXfO4LaTY)**
Video with short explanatión.

