Configuration and Reusability¶
Learn how to create reusable workflows with aliases, configuration files, and external scripts. This tutorial shows you how to avoid repeating yourself and share common patterns with your team.
What You'll Learn¶
- Create and use aliases with
--save-aliasand-a - Understand configuration file locations and precedence
- View and edit configuration with
--show-configand--edit-config - Write reusable functions with
-I/--include - Organize complex scripts with
-E/--exec-file - Decide when to use aliases vs includes vs exec-files
- Share workflows with your team
Prerequisites¶
- Basics: Input, Display & Filtering - Basic CLI usage
- Introduction to Rhai Scripting - Basic scripting knowledge
- Time: ~20 minutes
Sample Data¶
This tutorial uses:
examples/simple_json.jsonl- Application logs- Example configuration files we'll create
Part 1: Understanding Configuration Files¶
Configuration File Locations¶
Kelora searches for configuration in two places (in order):
- Project config -
.kelora.iniin current directory (or parent directories) - User config -
~/.config/kelora/kelora.ini(Unix) or%APPDATA%\kelora\kelora.ini(Windows)
Precedence: Project config overrides user config. CLI flags override both.
View Current Configuration¶
No config found (searched: .kelora.ini from cwd upward, /home/runner/.config/kelora/kelora.ini)
Example .kelora.ini:
defaults = -f auto --stats
[aliases]
errors = -l error --stats
json-errors = -f json -l error -F json
slow-requests = --filter 'e.response_time.to_int() > 1000' --keys timestamp,method,path,response_time
If no config exists, you'll see example templates and search paths.
Part 2: Creating Your First Alias¶
Aliases let you save commonly-used command patterns.
Save an Alias¶
Let's create an alias for finding errors:
This saves the alias to your user config file.
Use the Alias¶
Now you can use it with -a:
What happened: kelora -a errors expanded to kelora -j --levels error --keys timestamp,service,message.
Part 3: Configuration File Structure¶
Configuration files use INI format with two sections:
# Root-level defaults applied to every command
defaults = -f auto --stats
# Named aliases invoked with -a/--alias
[aliases]
errors = -j --levels error --keys timestamp,service,message
slow = -j --filter 'e.duration_ms > 1000' --keys service,duration_ms,message
problems = -j --levels error,warn,critical
Edit Your Configuration¶
This opens your active config file in $EDITOR (vi/vim/nano on Unix, notepad on Windows).
Part 4: Project vs User Configuration¶
User Configuration (Personal Preferences)¶
Location: ~/.config/kelora/kelora.ini
Good for:
- Personal formatting preferences
- Local development shortcuts
- Your own workflow patterns
Example:
defaults = --stats --no-emoji
[aliases]
myerrors = -j --levels error --exclude-keys password,token
quickcheck = -j --stats
Project Configuration (Team Shared)¶
Location: .kelora.ini in project root
Good for:
- Team-wide conventions
- Project-specific formats
- Shared analysis patterns
Example:
# Commit this to version control
defaults = -f json
[aliases]
api-errors = --levels error --filter 'e.service == "api"'
slow-db = --filter 'e.service == "database" && e.duration_ms > 100'
alerts = --levels critical,error --exec 'track_count(e.service)'
Pro tip: Commit .kelora.ini to your repository so the whole team uses the same patterns!
Part 5: Advanced Aliases¶
Chaining Multiple Aliases¶
Aliases can reference other aliases:
Limit: Aliases can reference up to 10 levels deep (prevents infinite loops).
Complex Aliases with Scripting¶
You can put full pipelines in aliases:
[aliases]
analyze-api = -j --filter 'e.service == "api"' \
--exec 'track_count(e.level)' \
--exec 'track_sum("total_duration", e.duration_ms)' \
--metrics
Tip: Use backslash \ for line continuation in INI files.
Part 6: Reusable Functions with --include¶
For complex logic, create reusable Rhai function libraries.
Create a Helper Library¶
We've created examples/helpers.rhai with useful functions:
// Reusable helper functions for log analysis
// Check if event is a problem (error or slow)
fn is_problem(event) {
let is_error = event.level == "ERROR" || event.level == "CRITICAL";
// Check for slow requests: response_time in seconds or duration_ms in milliseconds
let is_slow = (event.has("response_time") && event.response_time > 1.0) ||
(event.has("duration_ms") && event.duration_ms > 1000) ||
(event.has("latency_ms") && event.latency_ms > 1000);
is_error || is_slow
}
// Classify severity based on level and metrics
fn classify_severity(level, value) {
if level == "CRITICAL" || level == "ERROR" {
"high"
} else if level == "WARN" || value > 1000 {
"medium"
} else {
"low"
}
}
// Extract domain from URL or email
fn extract_domain(text) {
if text.contains("@") {
// Email format
let parts = text.split("@");
if parts.len() > 1 {
parts[1]
} else {
"unknown"
}
} else if text.contains("://") {
// URL format
let after_protocol = text.split("://")[1];
let domain_part = after_protocol.split("/")[0];
let without_port = domain_part.split(":")[0];
without_port
} else {
text
}
}
// Mask sensitive data
fn mask_sensitive(value) {
if value.len() <= 4 {
"***"
} else {
value.sub_string(0, 2) + "***" + value.sub_string(value.len() - 2, 2)
}
}
Use the Library¶
kelora -j examples/simple_json.jsonl \
-I examples/helpers.rhai \
--exec 'e.is_problem = is_problem(e)' \
--filter 'e.is_problem' \
-k service,level,is_problem,message
service='database' level='ERROR' is_problem=true message='Query timeout'
service='auth' level='ERROR' is_problem=true message='Account locked'
service='scheduler' level='INFO' is_problem=true message='Backup completed'
service='disk' level='CRITICAL' is_problem=true message='Disk space critical'
service='api' level='ERROR' is_problem=true message='Service unavailable'
How it works:
-I examples/helpers.rhailoads the function definitions- Functions become available in
--exec,--exec-file,--begin, and--endstages - Call them like any built-in function
Filter Limitations
--include does not work with --filter because filters must be pure expressions. Use --exec instead for filtering with custom functions.
Multiple Include Files¶
You can load multiple libraries:
kelora -j app.log \
-I lib/validators.rhai \
-I lib/transforms.rhai \
-I lib/metrics.rhai \
--exec 'e.valid = validate_event(e)' \
--filter 'e.valid'
Part 7: Complex Scripts with --exec-file¶
For longer transformations, put the entire script in a file.
Create a Transformation Script¶
We've created examples/enrich_events.rhai:
// This script enriches log events with additional computed fields
// Add timestamp metadata
if e.has("timestamp") {
let ts = e.timestamp;
if ts.contains("T") {
let parts = ts.split("T");
e.date = parts[0];
if parts.len() > 1 {
e.time = parts[1].split("Z")[0];
}
}
}
// Classify by severity
if e.has("level") {
e.severity = if e.level == "ERROR" || e.level == "CRITICAL" {
"high"
} else if e.level == "WARN" {
"medium"
} else {
"low"
};
}
// Add duration classification if present
// Handle response_time (seconds), duration_ms (milliseconds), or latency_ms (milliseconds)
let duration_in_ms = if e.has("response_time") {
e.response_time * 1000.0
} else if e.has("duration_ms") {
e.duration_ms
} else if e.has("latency_ms") {
e.latency_ms
} else {
-1.0
};
if duration_in_ms >= 0.0 {
e.speed = if duration_in_ms < 100.0 {
"fast"
} else if duration_in_ms < 1000.0 {
"normal"
} else {
"slow"
};
}
// Track by service and level
if e.has("service") && e.has("level") {
track_count(e.service + ":" + e.level);
}
// Return enriched event
e
Use the Script¶
kelora -j examples/simple_json.jsonl \
-E examples/enrich_events.rhai \
-k date,time,severity,speed,service,message \
--take 5
date='2024-01-15' time='10:00:00' severity='low' service='api' message='Application started'
date='2024-01-15' time='10:00:05' severity='low' service='api' message='Loading configuration'
date='2024-01-15' time='10:00:10' severity='low' service='database'
message='Connection pool initialized'
date='2024-01-15' time='10:01:00' severity='medium' service='api'
message='High memory usage detected'
date='2024-01-15' time='10:01:30' severity='high' speed='slow' service='database'
message='Query timeout'
kelora hint: Metrics recorded; rerun with -m or --metrics=json to view them.
Note: -E runs the script contents in the exec stage (once per event).
Part 8: When to Use What¶
Decision Matrix¶
| Need | Use | Why |
|---|---|---|
| Common flag combinations | Alias | Quick, sharable, version-controlled |
| Reusable functions | --include |
Define once, use in --exec/--begin/--end |
| Multi-step transformations | --exec-file |
Keep complex logic organized in files |
| Personal shortcuts | User config alias | Quick access to your patterns |
| Team conventions | Project config alias | Everyone uses same workflows |
| One-off commands | Plain CLI flags | No need to save |
Pattern Examples¶
Pattern 1: Personal Shortcut (User Alias)¶
# Save to user config
kelora -j --keys timestamp,message -b --save-alias quick
# Use anywhere
kelora -a quick any-file.log
Pattern 2: Team Convention (Project Alias)¶
# In .kelora.ini (commit to repo)
[aliases]
production-errors = -j --levels error,critical \
--filter 'e.environment == "production"' \
--exec 'track_count(e.service)'
# Anyone on team can run
kelora -a production-errors logs/*.jsonl --metrics
Pattern 3: Reusable Logic (Include File)¶
# lib/validation.rhai
fn is_valid_email(text) {
text.contains("@") && text.contains(".")
}
# Use in pipeline
kelora -j app.log \
-I lib/validation.rhai \
--filter 'is_valid_email(e.email)'
Pattern 4: Complex Pipeline (Exec File)¶
# transforms/normalize.rhai
// Normalize all fields
e.level = e.level.to_upper();
e.service = e.service.to_lower();
if e.has("duration_ms") {
e.duration_s = e.duration_ms / 1000;
}
track_count(e.service + ":" + e.level);
# Use in pipeline
kelora -j app.log -E transforms/normalize.rhai --metrics
Part 9: Real-World Workflow¶
Let's build a complete reusable workflow.
Step 1: Create Project Structure¶
Step 2: Create Shared Functions¶
Create scripts/helpers.rhai:
fn critical_event(e) {
e.level == "CRITICAL" ||
(e.level == "ERROR" && e.service == "database")
}
fn add_alert_tag(e) {
if critical_event(e) {
e.alert = true;
e.priority = "P1";
} else if e.level == "ERROR" {
e.alert = true;
e.priority = "P2";
}
}
Step 3: Create Transformation Script¶
Create scripts/enrich.rhai:
// Add computed fields
if e.has("duration_ms") {
e.duration_s = e.duration_ms / 1000;
e.slow = e.duration_ms > 1000;
}
// Classify severity
if e.has("level") {
e.severity = if e.level == "CRITICAL" || e.level == "ERROR" {
"high"
} else if e.level == "WARN" {
"medium"
} else {
"low"
};
}
Step 3: Create Project Config¶
Create .kelora.ini:
defaults = -f json --stats
[aliases]
errors = --levels error,critical -I scripts/helpers.rhai
enrich = -I scripts/helpers.rhai -E scripts/enrich.rhai
alerts = -a errors --exec 'add_alert_tag(e)' --filter 'e.alert'
analyze = -a enrich --exec 'track_count(e.severity)' --metrics
Step 4: Use the Workflow¶
# Quick error check
kelora -a errors app.log
# Full enrichment
kelora -a enrich app.log --take 10
# Generate alerts
kelora -a alerts app.log -F json -o alerts.json
# Analyze severity distribution
kelora -a analyze app.log
Step 5: Share with Team¶
Now your team can clone and run the same patterns!
Part 10: Configuration Best Practices¶
✅ Do¶
- Commit project
.kelora.ini- Share team conventions - Keep aliases focused - One purpose per alias
- Document in README - Explain what each alias does
- Use includes for functions - Reusable logic in files
- Version control scripts - Track changes to transforms
- Test aliases - Verify they work before committing
❌ Don't¶
- Don't put secrets in config - Use environment variables instead
- Don't make aliases too complex - Use exec-files for long scripts
- Don't override critical flags - Be careful with defaults
- Don't chain too deeply - Keep alias references simple
- Don't commit personal preferences - Use user config for those
Part 11: Troubleshooting¶
View Expanded Command¶
See what aliases expand to:
Ignore Configuration¶
Test without config:
Use Specific Config File¶
Test project config without affecting user config:
Check Include File Errors¶
Part 12: Advanced Techniques¶
Conditional Defaults¶
You can't have conditionals in INI, but you can create multiple configs:
# .kelora.dev.ini (development)
defaults = -f json --stats --verbose
# .kelora.prod.ini (production)
defaults = -f json -q
# Use specific config
kelora --config-file .kelora.dev.ini app.log
Environment-Specific Aliases¶
[aliases]
dev = -f json --stats --verbose
prod = -f json -q --strict
staging = -f json --stats
# Use based on environment
kelora -a $ENV app.log # where ENV=dev|prod|staging
Combining with Shell Scripts¶
Create analyze.sh:
#!/bin/bash
# Production log analyzer
set -e
LOG_FILE="$1"
OUTPUT_DIR="results"
mkdir -p "$OUTPUT_DIR"
# Run multiple analyses
kelora -a errors "$LOG_FILE" -o "$OUTPUT_DIR/errors.json"
kelora -a slow "$LOG_FILE" -o "$OUTPUT_DIR/slow.json"
kelora -a analyze "$LOG_FILE" > "$OUTPUT_DIR/metrics.txt"
echo "Analysis complete. Results in $OUTPUT_DIR/"
Summary¶
You've learned:
- ✅ Create aliases with
--save-aliasfor reusable commands - ✅ Use aliases with
-ato avoid repetition - ✅ Understand project vs user configuration
- ✅ View config with
--show-configand edit with--edit-config - ✅ Write reusable functions with
-I/--include - ✅ Organize complex scripts with
-E/--exec-file - ✅ Choose the right tool for each use case
- ✅ Share workflows with your team via version control
- ✅ Best practices for configuration management
Practice Exercises¶
Exercise 1: Create a Personal Alias¶
Create an alias for your most common log viewing pattern:
Solution
Exercise 2: Build a Helper Library¶
Create myhelpers.rhai with a function to check if a status code is an error:
Solution
Exercise 3: Create a Project Workflow¶
Set up a .kelora.ini for a web application with aliases for:
- API errors
- Slow requests
- Traffic analysis
Solution
Next Steps¶
Now that you can create reusable workflows, continue to:
- Advanced Scripting - Advanced transformation patterns
- Metrics and Tracking - Build analytics into your aliases
- Working with Time - Time-based filtering in aliases
Related guides:
- Concepts: Configuration System - Deep dive into config precedence
- How-To: Build a Service Health Snapshot - Real-world alias examples
- CLI Reference: Configuration Options - All config flags