@@ -51,7 +51,7 @@ public class UsageSanityChecker {
5151
5252 protected void reset () {
5353 errors = new StringBuilder ();
54- checkCases = new ArrayList <CheckCase >();
54+ checkCases = new ArrayList <>();
5555 }
5656
5757 protected boolean checkItemCountByPstmt () throws SQLException {
@@ -69,48 +69,51 @@ protected boolean checkItemCountByPstmt(CheckCase checkCase) throws SQLException
6969 /*
7070 * Check for item usage records which are created after it is removed
7171 */
72- try (PreparedStatement pstmt = conn .prepareStatement (checkCase .sqlTemplate )) {
73- if (checkCase .checkId ) {
74- pstmt .setInt (1 , lastId );
75- pstmt .setInt (2 , maxId );
76- }
77- try (ResultSet rs = pstmt .executeQuery ();) {
78- if (rs .next () && (rs .getInt (1 ) > 0 )) {
79- errors .append (String .format ("Error: Found %s %s\n " , rs .getInt (1 ), checkCase .itemName ));
80- checkOk = false ;
72+ try (PreparedStatement pstmt = conn .prepareStatement (checkCase .getSqlTemplate ())) {
73+ if (checkCase .isCheckId ()) {
74+ if (lastId > 0 ) {
75+ pstmt .setInt (1 , lastId );
76+ }
77+ if (maxId > lastId ) {
78+ pstmt .setInt (2 , maxId );
8179 }
82- }catch (Exception e )
83- {
84- s_logger .error ("checkItemCountByPstmt:Exception:" +e .getMessage ());
85- throw new CloudRuntimeException ("checkItemCountByPstmt:Exception:" +e .getMessage (),e );
8680 }
81+ checkOk = isCheckOkForPstmt (checkCase , checkOk , pstmt );
8782 }
8883 catch (Exception e )
8984 {
90- s_logger .error ("checkItemCountByPstmt:Exception:" +e .getMessage ());
91- throw new CloudRuntimeException ("checkItemCountByPstmt:Exception:" +e .getMessage (),e );
85+ throwPreparedStatementExcecutionException ("preparing statement" , checkCase .getSqlTemplate (), e );
86+ }
87+ return checkOk ;
88+ }
89+
90+ private boolean isCheckOkForPstmt (CheckCase checkCase , boolean checkOk , PreparedStatement pstmt ) {
91+ try (ResultSet rs = pstmt .executeQuery ();) {
92+ if (rs .next () && (rs .getInt (1 ) > 0 )) {
93+ errors .append (String .format ("Error: Found %s %s%n" , rs .getInt (1 ), checkCase .getItemName ()));
94+ checkOk = false ;
95+ }
96+ } catch (Exception e )
97+ {
98+ throwPreparedStatementExcecutionException ("check is failing" , pstmt .toString (), e );
9299 }
93100 return checkOk ;
94101 }
95102
103+ private static void throwPreparedStatementExcecutionException (String msgPrefix , String stmt , Exception e ) {
104+ String msg = String .format ("%s for prepared statement \" %s\" reason: %s" , msgPrefix , stmt , e .getMessage ());
105+ s_logger .error (msg );
106+ throw new CloudRuntimeException (msg , e );
107+ }
108+
96109 protected void checkMaxUsage () throws SQLException {
97110 int aggregationRange = DEFAULT_AGGREGATION_RANGE ;
98- try ( PreparedStatement pstmt = conn . prepareStatement (
99- "SELECT value FROM `cloud`.`configuration` where name = 'usage.stats.job.aggregation.range'" );)
111+ String sql = "SELECT value FROM `cloud`.`configuration` WHERE name = 'usage.stats.job.aggregation.range'" ;
112+ try ( PreparedStatement pstmt = conn . prepareStatement ( sql );)
100113 {
101- try (ResultSet rs = pstmt .executeQuery ();) {
102- if (rs .next ()) {
103- aggregationRange = rs .getInt (1 );
104- } else {
105- s_logger .debug ("Failed to retrieve aggregation range. Using default : " + aggregationRange );
106- }
107- }catch (SQLException e ) {
108- s_logger .error ("checkMaxUsage:Exception:" +e .getMessage ());
109- throw new CloudRuntimeException ("checkMaxUsage:Exception:" +e .getMessage ());
110- }
114+ aggregationRange = getAggregationRange (aggregationRange , pstmt );
111115 } catch (SQLException e ) {
112- s_logger .error ("checkMaxUsage:Exception:" +e .getMessage ());
113- throw new CloudRuntimeException ("checkMaxUsage:Exception:" +e .getMessage ());
116+ throwPreparedStatementExcecutionException ("preparing atatement" , sql , e );
114117 }
115118 int aggregationHours = aggregationRange / 60 ;
116119
@@ -120,6 +123,21 @@ protected void checkMaxUsage() throws SQLException {
120123 lastCheckId );
121124 }
122125
126+ private static int getAggregationRange (int aggregationRange , PreparedStatement pstmt ) {
127+ try (ResultSet rs = pstmt .executeQuery ();) {
128+ if (rs .next ()) {
129+ aggregationRange = rs .getInt (1 );
130+ } else {
131+ if (s_logger .isDebugEnabled ()) {
132+ s_logger .debug ("Failed to retrieve aggregation range. Using default : " + aggregationRange );
133+ }
134+ }
135+ } catch (SQLException e ) {
136+ throwPreparedStatementExcecutionException ("retrieval aggregate value is failing" , pstmt .toString (), e );
137+ }
138+ return aggregationRange ;
139+ }
140+
123141 protected void checkVmUsage () {
124142 addCheckCase ("select count(*) from cloud_usage.cloud_usage cu inner join cloud.vm_instance vm "
125143 + "where vm.type = 'User' and cu.usage_type in (1 , 2) "
@@ -170,14 +188,21 @@ protected void checkSnapshotUsage() {
170188 }
171189
172190 protected void readLastCheckId (){
191+ if (s_logger .isDebugEnabled ()) {
192+ s_logger .debug ("reading last checked id for sanity check" );
193+ }
173194 try (BufferedReader reader = new BufferedReader (new FileReader (lastCheckFile ));) {
174195 String lastIdText = null ;
175196 lastId = -1 ;
176- if ((reader != null ) && ( lastIdText = reader .readLine ()) != null ) {
197+ if ((lastIdText = reader .readLine ()) != null ) {
177198 lastId = Integer .parseInt (lastIdText );
178199 }
179200 } catch (Exception e ) {
180- s_logger .error ("readLastCheckId:Exception:" +e .getMessage (),e );
201+ String msg = String .format ("error reading the LastCheckId reason: %s" , e .getMessage ());
202+ s_logger .error (msg );
203+ s_logger .debug (msg , e );
204+ } finally {
205+ s_logger .info (String .format ("using %d as last checked id to start from in sanity check" , lastId ));
181206 }
182207 }
183208
@@ -188,20 +213,23 @@ protected void readMaxId() throws SQLException {
188213 maxId = -1 ;
189214 if (rs .next () && (rs .getInt (1 ) > 0 )) {
190215 maxId = rs .getInt (1 );
191- lastCheckId += " and cu.id <= ?" ;
216+ if (maxId > lastId ) {
217+ lastCheckId += " and cu.id <= ?" ;
218+ }
192219 }
193220 }catch (Exception e ) {
194221 s_logger .error ("readMaxId:" +e .getMessage (),e );
195222 }
196223 }
197224
198225 protected void updateNewMaxId () {
226+ s_logger .info (String .format ("writing %d as the new last id checked" , maxId ));
199227 try (FileWriter fstream = new FileWriter (lastCheckFile );
200- BufferedWriter out = new BufferedWriter (fstream );
228+ BufferedWriter out = new BufferedWriter (fstream );
201229 ){
202230 out .write ("" + maxId );
203231 } catch (IOException e ) {
204- s_logger .error ("updateNewMaxId: Exception:" + e .getMessage ());
232+ s_logger .error (String . format ( " Exception writing the last checked id: %d reason: %s" , maxId , e .getMessage () ));
205233 // Error while writing last check id
206234 }
207235 }
@@ -238,13 +266,17 @@ protected Connection getConnection() {
238266 return TransactionLegacy .getStandaloneConnection ();
239267 }
240268
241- public static void main (String args []) {
269+ /**
270+ * usage something like: /usr/bin/java -Xmx2G -cp /usr/share/cloudstack-usage/*:/usr/share/cloudstack-usage/lib/*:/usr/share/cloudstack-mysql-ha/lib/*:/etc/cloudstack/usage:/usr/share/java/mysql-connector-java.jar:/usr/share/cloudstack-common com.cloud.usage.UsageSanityChecker
271+ * @param args none
272+ */
273+ public static void main (String [] args ) {
242274 UsageSanityChecker usc = new UsageSanityChecker ();
243275 String sanityErrors ;
244276 try {
245277 sanityErrors = usc .runSanityCheck ();
246278 if (sanityErrors .length () > 0 ) {
247- s_logger .error (sanityErrors . toString () );
279+ s_logger .error (sanityErrors );
248280 }
249281 } catch (SQLException e ) {
250282 e .printStackTrace ();
@@ -266,19 +298,43 @@ protected void addCheckCase(String sqlTemplate, String itemName) {
266298 * encapsulating what change for each specific case
267299 */
268300class CheckCase {
269- public String sqlTemplate ;
270- public String itemName ;
271- public boolean checkId = false ;
301+ public String getSqlTemplate () {
302+ return this . sqlTemplate ;
303+ }
272304
273- public CheckCase (String sqlTemplate , String itemName , String lastCheckId ) {
274- checkId = true ;
275- this .sqlTemplate = sqlTemplate + lastCheckId ;
305+ public void setSqlTemplate (final String sqlTemplate ) {
306+ this .sqlTemplate = sqlTemplate ;
307+ }
308+
309+ public String getItemName () {
310+ return this .itemName ;
311+ }
312+
313+ public void setItemName (final String itemName ) {
276314 this .itemName = itemName ;
277315 }
278316
317+ public boolean isCheckId () {
318+ return this .checkId ;
319+ }
320+
321+ public void setCheckId (final boolean checkId ) {
322+ this .checkId = checkId ;
323+ }
324+
325+ private String sqlTemplate ;
326+ private String itemName ;
327+ private boolean checkId = false ;
328+
329+ public CheckCase (String sqlTemplate , String itemName , String lastCheckId ) {
330+ setCheckId (true );
331+ setSqlTemplate (sqlTemplate + lastCheckId );
332+ setItemName (itemName );
333+ }
334+
279335 public CheckCase (String sqlTemplate , String itemName ) {
280336 checkId = false ;
281- this . sqlTemplate = sqlTemplate ;
282- this . itemName = itemName ;
337+ setSqlTemplate ( sqlTemplate ) ;
338+ setItemName ( itemName ) ;
283339 }
284340}
0 commit comments