@minecraft-docker/mcctl 1.6.13 → 1.6.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,283 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # logs.sh - Log viewer for Minecraft servers
4
+ # =============================================================================
5
+ # View logs from Docker containers or log files.
6
+ #
7
+ # Usage:
8
+ # ./scripts/logs.sh <server> [options]
9
+ # ./scripts/logs.sh <server> -n <lines> # Show last N lines
10
+ # ./scripts/logs.sh <server> -f # Follow logs in real-time
11
+ # ./scripts/logs.sh <server> --file # View log file instead
12
+ # ./scripts/logs.sh router # View mc-router logs
13
+ # ./scripts/logs.sh avahi # View avahi-daemon logs (journalctl)
14
+ #
15
+ # Options:
16
+ # -n, --lines <N> Number of lines to show (default: 50)
17
+ # -f, --follow Follow log output in real-time
18
+ # --file Read from log file instead of Docker
19
+ # --timestamps Include timestamps in output
20
+ # --since <time> Show logs since timestamp (e.g., "10m", "1h")
21
+ # --json Output as JSON array
22
+ # -h, --help Show this help message
23
+ #
24
+ # Exit codes:
25
+ # 0 - Success
26
+ # 1 - Error
27
+ # 2 - Warning
28
+ # =============================================================================
29
+
30
+ set -e
31
+
32
+ # Get script directory and source common functions
33
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
34
+ PLATFORM_DIR="$(dirname "$SCRIPT_DIR")"
35
+ source "$SCRIPT_DIR/lib/common.sh"
36
+
37
+ # =============================================================================
38
+ # Configuration
39
+ # =============================================================================
40
+
41
+ DEFAULT_LINES=50
42
+ LOG_FILE_PATH="logs/latest.log"
43
+
44
+ # =============================================================================
45
+ # Usage
46
+ # =============================================================================
47
+
48
+ usage() {
49
+ cat <<EOF
50
+ Usage: $(basename "$0") <server> [options]
51
+
52
+ View logs from Minecraft servers (Docker or file-based).
53
+
54
+ Arguments:
55
+ <server> Server name (without mc- prefix)
56
+ Special values: router, avahi
57
+
58
+ Options:
59
+ -n, --lines <N> Number of lines to show (default: $DEFAULT_LINES)
60
+ -f, --follow Follow log output in real-time
61
+ --file Read from log file (servers/<server>/logs/latest.log)
62
+ --timestamps Include timestamps in Docker logs
63
+ --since <time> Show logs since time (e.g., "10m", "1h", "2024-01-17")
64
+ --json Output as JSON array
65
+ -h, --help Show this help message
66
+
67
+ Examples:
68
+ $(basename "$0") ironwood # Last 50 lines from Docker
69
+ $(basename "$0") ironwood -n 100 # Last 100 lines
70
+ $(basename "$0") ironwood -f # Follow in real-time
71
+ $(basename "$0") ironwood --file # Read from log file
72
+ $(basename "$0") ironwood --file -f # Follow log file
73
+ $(basename "$0") ironwood --json # JSON output
74
+ $(basename "$0") router # mc-router logs
75
+ $(basename "$0") avahi # avahi-daemon logs (journalctl)
76
+ $(basename "$0") ironwood --since 1h # Logs from last hour
77
+ EOF
78
+ }
79
+
80
+ # =============================================================================
81
+ # Docker Logs
82
+ # =============================================================================
83
+
84
+ docker_logs() {
85
+ local container="$1"
86
+ local lines="$2"
87
+ local follow="$3"
88
+ local timestamps="$4"
89
+ local since="$5"
90
+ local json_output="$6"
91
+
92
+ local args=()
93
+
94
+ # Build docker logs arguments
95
+ [[ -n "$lines" ]] && args+=("--tail" "$lines")
96
+ [[ "$follow" == "true" ]] && args+=("-f")
97
+ [[ "$timestamps" == "true" ]] && args+=("-t")
98
+ [[ -n "$since" ]] && args+=("--since" "$since")
99
+
100
+ if [[ "$json_output" == "true" ]]; then
101
+ # Collect logs and output as JSON
102
+ echo "["
103
+ local first=true
104
+ while IFS= read -r line; do
105
+ if [[ "$first" != "true" ]]; then
106
+ echo ","
107
+ fi
108
+ first=false
109
+ # Escape for JSON
110
+ local escaped
111
+ escaped=$(json_escape "$line")
112
+ printf ' "%s"' "$escaped"
113
+ done < <(docker logs "${args[@]}" "$container" 2>&1)
114
+ echo ""
115
+ echo "]"
116
+ else
117
+ docker logs "${args[@]}" "$container" 2>&1
118
+ fi
119
+ }
120
+
121
+ # =============================================================================
122
+ # File Logs
123
+ # =============================================================================
124
+
125
+ file_logs() {
126
+ local server="$1"
127
+ local lines="$2"
128
+ local follow="$3"
129
+ local json_output="$4"
130
+
131
+ local log_file="$PLATFORM_DIR/servers/$server/$LOG_FILE_PATH"
132
+
133
+ if [[ ! -f "$log_file" ]]; then
134
+ error "Log file not found: $log_file"
135
+ return 1
136
+ fi
137
+
138
+ if [[ "$json_output" == "true" ]]; then
139
+ echo "["
140
+ local first=true
141
+ while IFS= read -r line; do
142
+ if [[ "$first" != "true" ]]; then
143
+ echo ","
144
+ fi
145
+ first=false
146
+ local escaped
147
+ escaped=$(json_escape "$line")
148
+ printf ' "%s"' "$escaped"
149
+ done < <(tail -n "$lines" "$log_file")
150
+ echo ""
151
+ echo "]"
152
+ elif [[ "$follow" == "true" ]]; then
153
+ tail -f "$log_file"
154
+ else
155
+ tail -n "$lines" "$log_file"
156
+ fi
157
+ }
158
+
159
+ # =============================================================================
160
+ # Main
161
+ # =============================================================================
162
+
163
+ main() {
164
+ local server=""
165
+ local lines="$DEFAULT_LINES"
166
+ local follow=false
167
+ local file_mode=false
168
+ local timestamps=false
169
+ local since=""
170
+ local json_output=false
171
+
172
+ # Parse arguments
173
+ while [[ $# -gt 0 ]]; do
174
+ case "$1" in
175
+ -n|--lines)
176
+ lines="$2"
177
+ shift 2
178
+ ;;
179
+ -f|--follow)
180
+ follow=true
181
+ shift
182
+ ;;
183
+ --file)
184
+ file_mode=true
185
+ shift
186
+ ;;
187
+ --timestamps)
188
+ timestamps=true
189
+ shift
190
+ ;;
191
+ --since)
192
+ since="$2"
193
+ shift 2
194
+ ;;
195
+ --json)
196
+ json_output=true
197
+ JSON_OUTPUT=true
198
+ setup_colors
199
+ shift
200
+ ;;
201
+ -h|--help)
202
+ usage
203
+ exit 0
204
+ ;;
205
+ -*)
206
+ error "Unknown option: $1"
207
+ usage
208
+ exit 1
209
+ ;;
210
+ *)
211
+ if [[ -z "$server" ]]; then
212
+ server="$1"
213
+ else
214
+ error "Unexpected argument: $1"
215
+ usage
216
+ exit 1
217
+ fi
218
+ shift
219
+ ;;
220
+ esac
221
+ done
222
+
223
+ # Validate server argument
224
+ if [[ -z "$server" ]]; then
225
+ error "Server name is required"
226
+ usage
227
+ exit 1
228
+ fi
229
+
230
+ check_docker || exit 1
231
+
232
+ # Determine container name
233
+ local container
234
+ local use_journalctl=false
235
+ case "$server" in
236
+ router|mc-router)
237
+ container="mc-router"
238
+ server="router"
239
+ ;;
240
+ avahi|avahi-daemon)
241
+ # avahi-daemon is a system service, use journalctl
242
+ use_journalctl=true
243
+ server="avahi"
244
+ ;;
245
+ *)
246
+ container="mc-$server"
247
+ ;;
248
+ esac
249
+
250
+ # Handle avahi-daemon logs via journalctl
251
+ if $use_journalctl; then
252
+ info "Viewing avahi-daemon logs (system service via journalctl)"
253
+ local journal_opts="-u avahi-daemon --no-pager"
254
+ [[ -n "$lines" ]] && journal_opts="$journal_opts -n $lines"
255
+ [[ "$follow" == "true" ]] && journal_opts="$journal_opts -f"
256
+ [[ -n "$since" ]] && journal_opts="$journal_opts --since=$since"
257
+ # shellcheck disable=SC2086
258
+ run_with_sudo journalctl $journal_opts
259
+ exit 0
260
+ fi
261
+
262
+ # Check if using file mode
263
+ if $file_mode; then
264
+ if [[ "$server" == "router" ]]; then
265
+ error "File mode not supported for $server"
266
+ exit 1
267
+ fi
268
+ file_logs "$server" "$lines" "$follow" "$json_output"
269
+ else
270
+ # Check container exists
271
+ if ! container_exists "$container"; then
272
+ error "Container '$container' not found"
273
+ exit 1
274
+ fi
275
+
276
+ docker_logs "$container" "$lines" "$follow" "$timestamps" "$since" "$json_output"
277
+ fi
278
+ }
279
+
280
+ # Run main if script is executed directly
281
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
282
+ main "$@"
283
+ fi