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.3.tar.gz (13.7 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.3-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for execution_logger-1.1.3.tar.gz
Algorithm Hash digest
SHA256 533912b8b7aa98bd29796f703af44f349fc9dda557973a4b7fa6645d4a1d2773
MD5 0aeb4587d97ad8b1f6f6fa82700a899a
BLAKE2b-256 000f705d50e6df1c5af8eda122fa2cf01fecebd99118380eae2fe9c264c69842

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for execution_logger-1.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 bf3d0eae766911c88bd7f42f7ad2bddd4879326418a976f65cd1b8ab4c81b7cb
MD5 5b0fee85dd2802f85dde466c317b742b
BLAKE2b-256 1d5dfe12a7afbf81f6ddddee0a820b6307e8a1fa49cb4c9db3a6984e2f26d924

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