Skip to main content

A comprehensive Python logging solution with Microsoft SharePoint and Dataverse integration

Project description

ExecutionLogger

A Python logging solution with 3 storage options: Local files, SharePoint uploads, and optional Dataverse error tracking.

Quick Start

from execution_logger import ExecutionLogger

# Local only
logger = ExecutionLogger(script_name="my_app")
logger.info("Hello World")
logger.finalize()

Dependencies

pip install requests msal sharepoint-uploader

3 Storage Scenarios

1. Local Only

logger = ExecutionLogger(script_name="my_app")
  • Saves logs to script directory
  • No additional setup required

2. SharePoint Upload

logger = ExecutionLogger(
    script_name="my_app",
    client_id="your-azure-client-id",
    client_secret="your-azure-client-secret",
    tenant_id="your-azure-tenant-id",
    sharepoint_url="https://company.sharepoint.com/sites/sitename",
    drive_name="Documents",
    folder_path="Logs/MyApp"
)
  • Uploads logs to SharePoint using sharepoint-uploader
  • Requires Azure App Registration with SharePoint permissions

3. SharePoint + Dataverse

logger = ExecutionLogger(
    script_name="my_app",
    # SharePoint params (same as above)
    client_id="your-azure-client-id",
    client_secret="your-azure-client-secret", 
    tenant_id="your-azure-tenant-id",
    sharepoint_url="https://company.sharepoint.com/sites/sitename",
    drive_name="Documents",
    folder_path="Logs/MyApp",
    # Dataverse params (often same as SharePoint - see note below)
    dv_client_id="your-dataverse-client-id",  # Usually same as SharePoint
    dv_client_secret="your-dataverse-client-secret",  # Usually same as SharePoint
    dv_tenant_id="your-tenant-id",  # Usually same as SharePoint
    dv_scope="https://yourorg.crm.dynamics.com/.default",
    dv_api_url="https://yourorg.crm.dynamics.com/api/data/v9.0/your_table_name"
)
  • Uploads logs to SharePoint
  • Sends only errors to Dataverse table

💡 Microsoft Tools Integration: Since SharePoint and Dataverse are both Microsoft tools, you can typically use the same Azure App Registration for both services. This means client_id, client_secret, and tenant_id are often identical for SharePoint and Dataverse - just add the appropriate API permissions to one app registration.

Dataverse Table Setup

Required Table Structure

Create a Dataverse table with these exact column names:

Column Name Data Type Max Length Description
cr672_app Text 1000 Application name
cr672_message Text 1000 Error message
cr672_source Text 200 Error context
cr672_details Text 4000 Full error details with timestamp
cr672_id Text 50 Record identifier

Dataverse Table Creation Steps

  1. Go to Power Apps
  2. Select your environment
  3. DataTablesNew table
  4. Name: App Errors (or your preferred name)
  5. Add the 5 columns above with exact names and data types
  6. Save and publish

API URL Format

https://yourorg.crm.dynamics.com/api/data/v9.0/cr672_app_errors

Replace:

  • yourorg with your organization name
  • cr672_app_errors with your table's plural name

Azure App Registration Setup

💡 Single App Registration: Since SharePoint and Dataverse are both Microsoft tools, you can use one Azure App Registration for both services. Simply add permissions for both APIs to the same app.

For SharePoint Access

  1. Azure PortalApp RegistrationsNew registration
  2. Note Application (client) ID and Directory (tenant) ID
  3. Certificates & secrets → Create client secret
  4. API permissions → Add Microsoft GraphSites.ReadWrite.All
  5. Grant admin consent

For Dataverse Access (Same App Registration)

  1. Same app registrationAPI permissions → Add Dynamics CRMuser_impersonation
  2. Grant admin consent
  3. In Dataverse, assign appropriate security role to the app

Credential Reuse

When using the same app registration:

  • client_id = Same for both SharePoint and Dataverse
  • client_secret = Same for both SharePoint and Dataverse
  • tenant_id = Same for both SharePoint and Dataverse
  • Only dv_scope and dv_api_url are Dataverse-specific

Logging Methods

logger.info("Information message", "Optional details")
logger.warning("Warning message", "Warning context")
logger.error("Error message", "Error details")  # Only errors go to Dataverse
logger.debug("Debug message", "Debug context")
logger.critical("Critical message", "Critical details")

Parameter Reference

SharePoint Parameters (All required for SharePoint upload)

  • client_id: Azure app client ID
  • client_secret: Azure app client secret
  • tenant_id: Azure tenant ID
  • sharepoint_url: Site URL (e.g., https://company.sharepoint.com/sites/sitename)
  • drive_name: Document library name (e.g., Documents, Logs)
  • folder_path: Target folder (e.g., Logs/MyApp)

Dataverse Parameters (Optional)

  • dv_client_id: Dataverse app client ID (typically same as SharePoint client_id)
  • dv_client_secret: Dataverse app client secret (typically same as SharePoint client_secret)
  • dv_tenant_id: Dataverse tenant ID (typically same as SharePoint tenant_id)
  • dv_scope: Dataverse scope (e.g., https://yourorg.crm.dynamics.com/.default)
  • dv_api_url: Dataverse API endpoint (e.g., https://yourorg.crm.dynamics.com/api/data/v9.0/cr672_app_errors)

Note: Since both SharePoint and Dataverse are Microsoft services, most organizations use the same Azure App Registration for both, meaning the first three parameters are identical.

Other Parameters

  • local_log_directory: Custom local directory (defaults to script directory)
  • debug: Enable debug logging (default: False)

Error Handling

  • SharePoint upload fails: Warning logged, execution continues
  • Dataverse fails: Warning logged, execution continues
  • Authentication fails: Exception raised during initialization
  • Local save fails: Warning logged

Troubleshooting

SharePoint Issues

❌ sharepoint-uploader module not installed

Fix: pip install sharepoint-uploader

❌ Authentication failed

Fix: Check Azure app permissions and credentials

Dataverse Issues

❌ Failed to post error to Dataverse: 404

Fix: Verify table exists and API URL is correct

❌ Failed to post error to Dataverse: 401

Fix: Check app registration has Dataverse permissions

Common URL Formats

  • Correct SharePoint URL: https://company.sharepoint.com/sites/sitename
  • Wrong: https://company.sharepoint.com/sites/sitename/Shared Documents
  • Correct Dataverse URL: https://orgname.crm.dynamics.com/api/data/v9.0/tablename

Complete Example

import os
from execution_logger import ExecutionLogger

def main():
    # Using same Azure app registration for both SharePoint and Dataverse
    azure_client_id = os.getenv('AZURE_CLIENT_ID')
    azure_client_secret = os.getenv('AZURE_CLIENT_SECRET')
    azure_tenant_id = os.getenv('AZURE_TENANT_ID')
    
    logger = ExecutionLogger(
        script_name="daily_processor",
        # SharePoint
        client_id=azure_client_id,
        client_secret=azure_client_secret,
        tenant_id=azure_tenant_id,
        sharepoint_url="https://company.sharepoint.com/sites/logs",
        drive_name="Documents",
        folder_path="ApplicationLogs",
        # Dataverse (reusing same credentials)
        dv_client_id=azure_client_id,  # Same app registration
        dv_client_secret=azure_client_secret,  # Same app registration
        dv_tenant_id=azure_tenant_id,  # Same app registration
        dv_scope="https://company.crm.dynamics.com/.default",
        dv_api_url="https://company.crm.dynamics.com/api/data/v9.0/cr672_app_errors"
    )
    
    try:
        logger.info("Process started")
        # Your application logic
        process_data()
        logger.info("Process completed successfully")
    except Exception as e:
        logger.error("Process failed", f"Exception: {str(e)}")
    finally:
        logger.finalize()

if __name__ == "__main__":
    main()

Key Features

  • 3 flexible storage options: Local, SharePoint, or SharePoint + Dataverse
  • Automatic error tracking: Only errors sent to Dataverse
  • Robust error handling: Graceful degradation when services unavailable
  • Easy authentication: Uses proven sharepoint-uploader module
  • Production ready: Environment variable support and comprehensive logging

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

execution_logger-1.1.1.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

execution_logger-1.1.1-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file execution_logger-1.1.1.tar.gz.

File metadata

  • Download URL: execution_logger-1.1.1.tar.gz
  • Upload date:
  • Size: 13.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.9

File hashes

Hashes for execution_logger-1.1.1.tar.gz
Algorithm Hash digest
SHA256 b844ad2965a13ef300648d79d090d663d686c77c634d0e9af69953ac6fa1c63f
MD5 27304ebe2b52205aa6c44479ab6638fd
BLAKE2b-256 042d41d02e739f02d3dc903ae226b8f7d43c072fa47ec7fe10420b64ca42303f

See more details on using hashes here.

File details

Details for the file execution_logger-1.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for execution_logger-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6fa7b725787b4ba36800b1231a522a1cfd0ea125e99416c11a134ad444b92010
MD5 f3151080fdc604fac3bb317fd7ecbd37
BLAKE2b-256 a1194ad8296e7a6f3daa4cfc42aefb1f898c5a55709b2f46298976b0c7c146ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page