A virtual printer for macOS that automatically indexes print jobs in Elasticsearch for searchability and cloud storage. Perfect for archiving and searching web pages from your browser!
Print any web page from Safari, Chrome, or Firefox directly to Elasticsearch:
- π° Archive articles and research materials with full-text search
- π Save documentation for offline access and quick lookup
- π Search across all saved pages instantly
- βοΈ Compliance archiving with automatic timestamping
- π§ Build a personal knowledge base from web content
See Browser Printing Guide for detailed instructions.
- Browser Integration: Print web pages directly from Safari, Chrome, Firefox, or any macOS app
- Virtual Printer Integration: Seamlessly integrates with macOS printing system using CUPS
- Automatic Content Extraction: Captures print job content and indexes in Elasticsearch
- Elasticsearch Indexing: Automatically posts documents to Elasticsearch with full-text search capability
- Metadata Extraction: Captures job metadata (user, timestamp, title, hostname)
- Content Search: Uses Elasticsearch ingest attachment pipeline to extract searchable text
- Flexible Configuration: YAML-based configuration for easy customization
- Serverless Compatible: Works with Elasticsearch Serverless clusters
- macOS 10.15 (Catalina) or later
- Python 3.9 or higher
- CUPS (pre-installed on macOS)
- Elasticsearch 8.0+ cluster (including Serverless)
- Network access to Elasticsearch
- API Key for authentication (recommended) or basic auth credentials
git clone https://github.com/yourusername/elasticprinter.git
cd elasticprinterCopy the example configuration and edit with your Elasticsearch settings:
sudo mkdir -p /etc/elasticprinter
sudo cp config/config.yaml.example /etc/elasticprinter/config.yaml
sudo nano /etc/elasticprinter/config.yamlUpdate the following settings:
elasticsearch.host: Your Elasticsearch URL (including port, e.g.,https://your-cluster.elastic.cloud:443)elasticsearch.api_key: Your encoded API key (recommended for Serverless)- Or use
elasticsearch.api_key_idandelasticsearch.api_key: For tuple-based authentication - Or use
usernameandpasswordfor basic auth
Note: For Elasticsearch Serverless, use the encoded API key format.
Run the installation script (requires sudo):
sudo ./scripts/install_printer.shThis will:
- Install Python dependencies system-wide
- Install the CUPS backend at
/usr/libexec/cups/backend/elasticprinter - Install the PPD file at
/Library/Printers/PPDs/Contents/Resources/ - Register the ElasticPrinter with CUPS
- Create necessary directories (
/tmp/elasticprinter,/var/log/elasticprinter) - Set appropriate permissions
The printer will automatically create the index and pipeline on first use, or you can pre-create them:
# The index and pipeline are created automatically when the first document is indexed
# Or manually create using the Elasticsearch APIAfter installation, enable the printer:
sudo cupsenable ElasticPrinterThat's it! Now print any web page:
- Open Safari, Chrome, or Firefox
- Navigate to any web page
- Press
βP(Command+P) or select File β Print - Choose ElasticPrinter from the printer dropdown
- Click Print
Your web page is now indexed and searchable in Elasticsearch! π
If your print job doesn't appear in Elasticsearch within 30 seconds, run:
sudo python3 scripts/process_stuck_jobs.pyThis processes any stuck jobs in the CUPS queue. See Chrome Workaround Guide for details and alternative solutions.
π‘ Most Reliable Method:
For important pages, use Print β Save as PDF β then print the PDF to ElasticPrinter. This works 100% of the time!
See the Browser Printing Guide for:
- Browser-specific instructions
- Optimal print settings
- Workflow examples
- Searching your archived pages
You can test the backend directly:
echo "Test document - $(date)" | sudo -u _lp /usr/libexec/cups/backend/elasticprinter 1001 testuser "Test Document" 1 ""Or print from any application and select "ElasticPrinter" as your printer!
From Safari:
- Navigate to any web page
- Press
βP(Command+P) - Select ElasticPrinter
- Optionally customize the title for easier searching
- Click Print
From Chrome/Firefox:
- Navigate to any web page
- Press
βP(Command+P) - Select ElasticPrinter as destination
- Click Print
Best Practices:
- Use descriptive titles (e.g., "AWS Lambda Docs - Python")
- Enable "Print Backgrounds" for better formatting
- Use 100% scale for optimal text extraction
See Browser Printing Guide for detailed instructions and examples.
- Open any document in macOS (PDF, Word, Pages, etc.)
- Choose File β Print (Cmd+P)
- Select "ElasticPrinter" from the printer list
- Click Print
The document will be:
- Converted to PDF
- Indexed in Elasticsearch
- Searchable via the Elasticsearch cluster
Use Elasticsearch queries to search your printed web pages and documents:
# Search for web pages containing "kubernetes" (replace with your Elasticsearch URL and API key)
curl -X GET "https://your-cluster.elastic.cloud:443/print-jobs/_search?pretty" \
-H 'Content-Type: application/json' \
-H 'Authorization: ApiKey YOUR_ENCODED_API_KEY' \
-d'
{
"query": {
"match": {
"attachment.content": "kubernetes"
}
},
"highlight": {
"fields": {
"attachment.content": {}
}
}
}
'
# Search by title (e.g., find all AWS documentation)
curl -X GET "https://your-cluster.elastic.cloud:443/print-jobs/_search?pretty" \
-H 'Content-Type: application/json' \
-H 'Authorization: ApiKey YOUR_ENCODED_API_KEY' \
-d'
{
"query": {
"match": {
"print_job.title": "AWS"
}
}
}
'
# Get a specific document by ID
curl -H "Authorization: ApiKey YOUR_ENCODED_API_KEY" \
"https://your-cluster.elastic.cloud:443/print-jobs/_doc/print-job-1001"
# List recent documents
curl -H "Authorization: ApiKey YOUR_ENCODED_API_KEY" \
"https://your-cluster.elastic.cloud:443/print-jobs/_search?size=10&sort=indexed_at:desc"tail -f /var/log/elasticprinter/app.loglpstat -p ElasticPrinterThe configuration file is located at /etc/elasticprinter/config.yaml and supports the following options:
elasticsearch:
host: "https://your-cluster.elastic.cloud:443" # Include port
# For Serverless or encoded API key:
api_key: "your_encoded_api_key"
# OR for tuple-based API key:
# api_key_id: "your_api_key_id"
# api_key: "your_api_key_secret"
# OR for basic auth:
# username: "elastic"
# password: "your_password"
index: "print-jobs"
pipeline: "attachment"
verify_certs: true
printer:
name: "ElasticPrinter"
description: "Virtual Printer to Elasticsearch"
location: "Cloud Storage"
processing:
temp_dir: "/tmp/elasticprinter"
keep_pdfs: false # Set to true for debugging
max_retries: 3
timeout: 30
logging:
level: "INFO" # DEBUG, INFO, WARNING, ERROR
file: "/var/log/elasticprinter/app.log"Print Job β CUPS β ElasticPrinter Backend β Content Processing β Elasticsearch
β β
Read from stdin Metadata Extraction
β
Ingest Pipeline (attachment)
- CUPS Backend (
/usr/libexec/cups/backend/elasticprinter): Receives print jobs from macOS printing system - Content Processing: Saves print job content (PostScript/text) for indexing
- Metadata Extractor: Extracts job metadata (user, title, timestamp, hostname) and PDF metadata
- Elasticsearch Client: Indexes content with metadata using ingest attachment pipeline
- Attachment Pipeline: Elasticsearch extracts searchable text from the document
-
Python Package: Installed at
/Library/Python/3.9/site-packages/converter/: Content handling and processingelastic/: Elasticsearch client and indexingutils/: Configuration, logging utilitieselasticprinter_backend/: Main orchestrator
-
CUPS Integration:
- Backend:
/usr/libexec/cups/backend/elasticprinter - PPD:
/Library/Printers/PPDs/Contents/Resources/ElasticPrinter.ppd
- Backend:
-
Configuration:
/etc/elasticprinter/config.yaml -
Logs:
/var/log/elasticprinter/app.log -
Temporary Files:
/tmp/elasticprinter/
# Check if printer is registered
lpstat -p ElasticPrinter
# Re-install if needed
sudo ./scripts/uninstall_printer.sh
sudo ./scripts/install_printer.shCheck the logs:
tail -f /var/log/elasticprinter/app.log
# Or check CUPS logs
sudo tail -f /var/log/cups/error_logCommon issues:
- Elasticsearch connection failed: Check network, credentials, and firewall rules
- Permission denied: Ensure
/tmp/elasticprinterand/var/log/elasticprinter/app.logare writable - Printer disabled: Run
sudo cupsenable ElasticPrinter - No logs appearing: Backend might not be executing - check CUPS error log
The best way to test is to run the backend directly:
# Test as the CUPS user (_lp)
echo "Test content - $(date)" | sudo -u _lp /usr/libexec/cups/backend/elasticprinter 999 testuser "Test" 1 ""
# Check if document was indexed
curl -H "Authorization: ApiKey YOUR_API_KEY" \
"https://your-cluster.elastic.cloud:443/print-jobs/_doc/print-job-999"# Quick connection test
curl -H "Authorization: ApiKey YOUR_ENCODED_API_KEY" \
"https://your-cluster.elastic.cloud:443/_cluster/health"
# Test with Python
sudo python3 -c "
from utils.config_loader import ConfigLoader
from elastic.client import ElasticClient
config = ConfigLoader('/etc/elasticprinter/config.yaml')
es_config = config.elasticsearch
client = ElasticClient(
host=es_config.get('host'),
api_key=es_config.get('api_key'),
index=es_config.get('index')
)
print('Connected successfully!')
"To remove ElasticPrinter:
sudo ./scripts/uninstall_printer.shpython3 -m pytest tests/elasticprinter/
βββ src/
β βββ converter/ # PDF generation and conversion
β βββ elastic/ # Elasticsearch integration
β βββ utils/ # Configuration and logging
β βββ main.py # Main orchestrator
βββ printer/
β βββ backend/ # CUPS backend script
β βββ elasticprinter.ppd # Printer definition
βββ scripts/ # Installation scripts
βββ config/ # Configuration templates
βββ tests/ # Unit tests
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details
For issues and questions, please open an issue on GitHub.
- OCR support for scanned documents
- Web UI for searching and retrieving documents
- Multi-tenancy support
- Cloud storage integration (S3, Azure Blob)
- macOS Settings extension
- Notification on successful indexing