15.4. 15.5 Packaging and Version Control#
15.4.1. Version Control with Git#
15.4.1.1. Repository Structure#
Initialize a professional Git repository:
# Create repository
mkdir monitoring-system
cd monitoring-system
git init
# Create .gitignore
cat > .gitignore << 'EOF'
# Logs and runtime data
*.log
*.db
*.tmp
/logs/*
/var/*
# Configuration with secrets
config/secrets.conf
config/production.conf
# IDE files
.vscode/
.idea/
*.swp
*.swo
# Dependencies (if using installer)
vendor/
/usr/local/
# Test artifacts
/tmp/
/.test-*
# OS files
.DS_Store
Thumbs.db
EOF
git add .gitignore
git commit -m "Initial commit: add gitignore"
15.4.1.2. Commit Message Strategy#
Use conventional commits for clear history:
# Feature: new alert channel
git commit -m "feat: add PagerDuty webhook support for critical alerts"
# Bug fix: memory leak
git commit -m "fix: prevent duplicate alerts when threshold lingering"
# Documentation
git commit -m "docs: update README with installation instructions"
# Refactoring
git commit -m "refactor: consolidate metric parsing into lib/metrics.sh"
# Testing
git commit -m "test: add integration tests for alert escalation"
# Performance
git commit -m "perf: optimize log parsing with compiled regex"
15.4.1.3. Branching Strategy#
Use feature branches for development:
# Create feature branch
git checkout -b feature/pagerduty-integration
# Make changes
# Commit regularly
git commit -m "..."
# Push to remote
git push origin feature/pagerduty-integration
# Create pull request for review
# After approval and tests pass, merge to main
git checkout main
git merge feature/pagerduty-integration
git push origin main
15.4.2. Installation and Deployment#
15.4.2.1. Installation Script#
Create an installer for easy deployment:
#!/bin/bash
# install.sh - Install monitoring system
set -euo pipefail
INSTALL_PREFIX="${INSTALL_PREFIX:-/opt/monitoring-system}"
CONFIG_PREFIX="${CONFIG_PREFIX:-/etc/monitoring-system}"
check_prerequisites() {
local deps=("bash" "sqlite3" "curl" "awk" "sed" "mail")
echo "Checking prerequisites..."
for cmd in "${deps[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
echo "ERROR: Required command not found: $cmd"
return 1
fi
done
echo "✓ All prerequisites satisfied"
}
create_directories() {
echo "Creating directories..."
mkdir -p "$INSTALL_PREFIX"/{src,lib,tests}
mkdir -p "$CONFIG_PREFIX"
mkdir -p /var/log/monitoring-system
mkdir -p /var/lib/monitoring-system
echo "✓ Directories created"
}
install_files() {
echo "Installing files..."
# Copy source files
cp src/*.sh "$INSTALL_PREFIX/src/"
chmod 755 "$INSTALL_PREFIX/src"/*.sh
# Copy libraries
cp lib/*.sh "$INSTALL_PREFIX/lib/"
chmod 644 "$INSTALL_PREFIX/lib"/*.sh
# Copy configuration templates
cp config/monitoring-system.conf.example "$CONFIG_PREFIX/monitoring-system.conf"
cp config/alert-rules.conf.example "$CONFIG_PREFIX/alert-rules.conf"
cp config/thresholds.conf.example "$CONFIG_PREFIX/thresholds.conf"
chmod 600 "$CONFIG_PREFIX"/*.conf
echo "✓ Files installed"
}
initialize_database() {
echo "Initializing database..."
local db_path="/var/lib/monitoring-system/metrics.db"
sqlite3 "$db_path" < schema.sql
chmod 600 "$db_path"
echo "✓ Database initialized at $db_path"
}
install_systemd_service() {
echo "Installing systemd service..."
local service_dir="/etc/systemd/system"
cp systemd/monitoring-collector.service "$service_dir/"
cp systemd/monitoring-collector.timer "$service_dir/"
systemctl daemon-reload
# Optionally enable
read -p "Enable monitoring service? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
systemctl enable monitoring-collector.timer
systemctl start monitoring-collector.timer
echo "✓ Service enabled and started"
fi
}
main() {
echo "=== Monitoring System Installation ==="
echo "Install prefix: $INSTALL_PREFIX"
echo "Config prefix: $CONFIG_PREFIX"
echo
check_prerequisites || exit 1
create_directories
install_files
initialize_database
install_systemd_service
echo
echo "=== Installation Complete ==="
echo "Next steps:"
echo "1. Edit configuration: $CONFIG_PREFIX/monitoring-system.conf"
echo "2. Review thresholds: $CONFIG_PREFIX/thresholds.conf"
echo "3. Check logs: /var/log/monitoring-system/"
echo "4. Run health check: $INSTALL_PREFIX/src/health-check.sh"
}
main "$@"
15.4.2.2. Uninstaller#
#!/bin/bash
# uninstall.sh - Remove monitoring system
set -euo pipefail
read -p "Remove monitoring system? This cannot be undone. (yes/no) " response
if [[ "$response" != "yes" ]]; then
echo "Aborted"
exit 0
fi
echo "Stopping services..."
systemctl stop monitoring-collector.timer
systemctl stop monitoring-collector.service
systemctl disable monitoring-collector.timer
echo "Removing files..."
rm -rf /opt/monitoring-system
rm -rf /etc/systemd/system/monitoring-collector.*
echo "Archiving data..."
tar -czf /tmp/monitoring-system-backup-$(date +%s).tar.gz /var/lib/monitoring-system
rm -rf /var/lib/monitoring-system
echo "Cleaning up logs..."
rm -rf /var/log/monitoring-system
systemctl daemon-reload
echo "Uninstall complete"
15.4.3. Documentation#
15.4.3.1. README.md#
# Server Monitoring and Alert System
A production-grade monitoring system built in Bash for tracking system metrics,
aggregating logs, and triggering intelligent alerts.
## Features
- **Real-time Metrics** - CPU, memory, disk, network monitoring
- **Log Aggregation** - Parse and correlate logs from multiple sources
- **Smart Alerting** - Threshold and pattern-based alerts with multiple channels
- **Reporting** - HTML dashboards, CSV exports, historical trends
- **Scalable** - Designed for 50+ monitored hosts
- **Production-Ready** - Comprehensive error handling, testing, documentation
## Installation
```bash
git clone https://github.com/yourorg/monitoring-system.git
cd monitoring-system
sudo bash install.sh
15.4.4. Configuration#
Edit /etc/monitoring-system/monitoring-system.conf:
# Alert channels
ENABLE_EMAIL=true
EMAIL_TO=admin@example.com
ENABLE_SLACK=true
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
# Thresholds
CPU_THRESHOLD=85
MEMORY_THRESHOLD=90
DISK_THRESHOLD=95
# Data retention
METRICS_RETENTION_DAYS=90
LOG_RETENTION_DAYS=30
15.4.5. Usage#
The system runs automatically via systemd timer. To manually run:
/opt/monitoring-system/src/metrics-collector.sh
/opt/monitoring-system/src/log-aggregator.sh
/opt/monitoring-system/src/alert-engine.sh
/opt/monitoring-system/src/report-generator.sh
View logs:
journalctl -u monitoring-collector.service
tail -f /var/log/monitoring-system/metrics.log
15.4.6. Troubleshooting#
15.4.7. License#
MIT
### INSTALL.md
Detailed installation guide for different platforms (Ubuntu, CentOS, etc.)
### CONFIGURATION.md
Complete reference for all configuration options
### TROUBLESHOOTING.md
Common issues and solutions
## Distribution
### Create Release Package
```bash
#!/bin/bash
# build-release.sh - Create distributable package
set -euo pipefail
VERSION="${1:-1.0.0}"
PACKAGE_NAME="monitoring-system-$VERSION"
# Create clean build directory
rm -rf build
mkdir -p build/$PACKAGE_NAME
# Copy files
cp -r src build/$PACKAGE_NAME/
cp -r lib build/$PACKAGE_NAME/
cp -r config build/$PACKAGE_NAME/
cp -r systemd build/$PACKAGE_NAME/
cp -r tests build/$PACKAGE_NAME/
cp -r docs build/$PACKAGE_NAME/
cp *.sh build/$PACKAGE_NAME/
cp .gitignore build/$PACKAGE_NAME/
cp LICENSE build/$PACKAGE_NAME/
# Create tarball
cd build
tar -czf "../$PACKAGE_NAME.tar.gz" "$PACKAGE_NAME"
cd ..
# Create checksum
sha256sum "$PACKAGE_NAME.tar.gz" > "$PACKAGE_NAME.tar.gz.sha256"
echo "Release package created: $PACKAGE_NAME.tar.gz"
echo "SHA256: $(cat $PACKAGE_NAME.tar.gz.sha256)"
# Clean up
rm -rf build
15.4.7.1. Docker Support (Optional)#
Create a Dockerfile for containerized deployment:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
bash \
sqlite3 \
curl \
mailutils
WORKDIR /opt/monitoring-system
COPY . .
RUN bash install.sh --no-systemd
CMD ["/opt/monitoring-system/src/metrics-collector.sh"]
15.4.8. Summary#
Your monitoring system is now:
✓ Professionally packaged and versioned
✓ Easy to install and configure
✓ Thoroughly documented
✓ Ready for distribution
✓ Suitable for production deployment
15.4.9. Deployment Checklist#
Before deploying version 1.0.0:
All tests passing locally
Code review completed
Documentation updated
Version number bumped in all files
Git tag created and pushed
Release notes written
Installation tested on target OS
Configuration examples provided
Uninstall script tested
Backup strategy documented
Rollback plan prepared
Health check validates installation
15.4.10. Professional Release Announcement#
Example announcement for release v1.0.0:
# Monitoring System v1.0.0 Released
We're excited to announce the first stable release of the Monitoring System!
## What's New
- Real-time metrics collection (CPU, memory, disk, network)
- Intelligent alerting with multiple notification channels
- Beautiful HTML dashboards and CSV exports
- Production-grade error handling and logging
- Comprehensive documentation and examples
## Installation
```bash
wget https://github.com/yourorg/monitoring-system/releases/download/v1.0.0/monitoring-system-1.0.0.tar.gz
tar -xzf monitoring-system-1.0.0.tar.gz
sudo bash install.sh
15.4.11. Key Features#
Scalable: Monitors 50+ hosts efficiently
Reliable: Comprehensive error handling and recovery
Maintainable: Well-tested, documented codebase
Extensible: Easy to add custom metrics and alerts
15.4.12. Documentation#
15.4.13. Thanks#
This project builds on the Bash scripting best practices from our comprehensive course.
Release Notes | Source Code | Issues
#!/bin/bash
# Example: Setting up a professional project with Git and tooling
# Initialize project directory
init_project() {
local project_name="$1"
cd /tmp
mkdir -p "$project_name"
cd "$project_name"
# Create directory structure
mkdir -p src lib config tests docs systemd
# Create standard files
touch README.md LICENSE CHANGELOG.md .gitignore
# Initialize Git
git init
git config user.name "Developer"
git config user.email "dev@example.com"
# Create .gitignore
cat > .gitignore << 'EOF'
*.log
*.db
*.tmp
__pycache__/
.pytest_cache/
*.pyc
.vscode/
.idea/
*.swp
EOF
# Initial commit
git add .
git commit -m "Initial commit: project skeleton"
echo "Project initialized: $project_name"
pwd
}
# Create version file
create_version_file() {
cat > src/version.sh << 'EOF'
#!/bin/bash
# Project version information
PROJECT_NAME="monitoring-system"
PROJECT_VERSION="1.0.0"
PROJECT_AUTHOR="Your Name"
PROJECT_URL="https://github.com/yourorg/monitoring-system"
show_version() {
cat << VERSIONEOF
$PROJECT_NAME version $PROJECT_VERSION
Copyright (c) 2024 $PROJECT_AUTHOR
$PROJECT_URL
VERSIONEOF
}
show_version "$@"
EOF
chmod +x src/version.sh
git add src/version.sh
git commit -m "chore: add version script"
}
# Create build script
create_build_script() {
cat > build.sh << 'EOF'
#!/bin/bash
# Build and package the project
set -euo pipefail
VERSION="${VERSION:-1.0.0}"
DIST_DIR="dist"
mkdir -p "$DIST_DIR"
echo "Building version $VERSION..."
# Copy files
cp -r src lib config tests docs LICENSE README.md "$DIST_DIR/"
# Create tarball
cd "$DIST_DIR"
tar -czf "../monitoring-system-$VERSION.tar.gz" .
cd ..
# Create checksum
sha256sum "monitoring-system-$VERSION.tar.gz" > "monitoring-system-$VERSION.tar.gz.sha256"
echo "Build complete: monitoring-system-$VERSION.tar.gz"
echo "Checksum: $(cat monitoring-system-$VERSION.tar.gz.sha256)"
rm -rf "$DIST_DIR"
EOF
chmod +x build.sh
git add build.sh
git commit -m "chore: add build script"
}
# Main setup
main() {
local project="monitoring-system"
init_project "$project"
create_version_file
create_build_script
echo
echo "Project setup complete!"
echo "Git log:"
git log --oneline
}
main "$@"
Cell In[1], line 6
local project_name="$1"
^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
15.4.14. Git Workflow for Your Project#
15.4.14.1. Initialize Repository#
# Create and initialize
mkdir my-capstone-project
cd my-capstone-project
git init
# Create initial structure
mkdir -p src lib config tests docs systemd
touch .gitignore README.md LICENSE
# First commit
git add .
git commit -m "Initial commit: project structure"
15.4.14.2. Development Workflow#
Create feature branch:
git checkout -b feature/core-metrics-collection
# Make changes...
git add src/metrics-collector.sh lib/logging.sh
git commit -m "feat: implement metrics collection from /proc"
Keep commits atomic:
# GOOD: Focused change
git commit -m "fix: handle missing /proc/meminfo gracefully"
# BAD: Too broad
git commit -m "Updated stuff"
Before pushing, clean up history:
# Squash related commits
git rebase -i HEAD~3
# Or review changes before push
git log --oneline -5
git diff origin/main...HEAD
15.4.14.3. Release Process#
# Create release branch
git checkout -b release/v1.0.0
# Update version numbers
sed -i 's/VERSION="0.9.0"/VERSION="1.0.0"/' src/health-check.sh
# Update changelog
cat >> CHANGELOG.md << 'EOF'
## Version 1.0.0 - 2024-01-15
### Features
- Complete metrics collection implementation
- Multi-channel alerting (email, Slack, webhooks)
- HTML dashboard and CSV reporting
### Bug Fixes
- Fixed database locking issues
- Improved error handling for missing logs
### Documentation
- Installation guide for Ubuntu/CentOS
- Configuration reference
- Troubleshooting guide
EOF
# Commit and tag
git add -u
git commit -m "chore: bump version to 1.0.0"
git tag -a v1.0.0 -m "Release version 1.0.0"
15.4.15. Distribution Strategies#
15.4.15.1. Strategy 1: GitHub Release#
# Create release on GitHub with tarball
git push origin v1.0.0
# On GitHub UI:
# - Create Release from tag
# - Upload monitoring-system-1.0.0.tar.gz
# - Upload SHA256 checksum
# - Add release notes
15.4.15.2. Strategy 2: Package Manager (Debian/Ubuntu)#
Create debian/ directory structure:
debian/
├── control # Package metadata
├── rules # Build rules
├── changelog # Version history
├── copyright # License
└── monitoring-system.service
# Build:
dpkg-buildpackage -us -uc
# Creates: monitoring-system_1.0.0_all.deb
# Install:
sudo dpkg -i monitoring-system_1.0.0_all.deb
15.4.15.3. Strategy 3: Container Image#
# Dockerfile
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
bash sqlite3 curl mailutils
WORKDIR /opt/app
COPY . .
RUN bash install.sh --no-systemd
VOLUME ["/var/lib/monitoring-system", "/var/log/monitoring-system"]
EXPOSE 8080
ENTRYPOINT ["./src/metrics-collector.sh"]
Build and publish:
docker build -t myorg/monitoring-system:1.0.0 .
docker push myorg/monitoring-system:1.0.0
15.4.16. License and Legal#
Choose an appropriate license:
MIT License (simple, permissive):
MIT License
Copyright (c) 2024 [Your Name]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction...
Apache 2.0 License (includes patent protection):
Apache License
Version 2.0, January 2004
...
15.4.17. Documentation Structure#
Create comprehensive docs:
docs/
├── README.md # Overview and quick start
├── INSTALL.md # Detailed installation
├── USAGE.md # Usage examples
├── CONFIGURATION.md # Configuration reference
├── ARCHITECTURE.md # System design
├── TROUBLESHOOTING.md # Common issues
├── CONTRIBUTING.md # How to contribute
├── API.md # API documentation
└── examples/ # Usage examples
├── basic-setup.sh
├── custom-alert.sh
└── advanced-config.conf
15.4.18. CHANGELOG Maintenance#
Keep a detailed changelog:
# Changelog
All notable changes to this project will be documented in this file.
## [Unreleased]
### Added
- New webhook notification support
- Custom alert rule scripting
### Changed
- Improved log parsing performance by 30%
### Fixed
- Memory leak in alert engine
## [1.0.0] - 2024-01-15
### Added
- Initial release with core features
- Metrics collection (CPU, memory, disk, network)
- Multi-channel alerting
- HTML reporting
### Known Limitations
- Single-host monitoring only
- SQLite not suitable for 100+ years of data
15.4.19. Continuous Integration (Optional)#
Set up automated testing on each commit:
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run unit tests
run: bash tests/unit-tests.sh
- name: Run integration tests
run: bash tests/integration-tests.sh
- name: Check code quality
run: bash -n src/*.sh lib/*.sh
Your project is now production-ready and professionally packaged!